We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
https://wolfdu.fun/post?postId=5a473e9a25322c62a62e7b15
new运算符:
new 运算符创建一个自定义对象或具有构造函数的内置对象的实例。
(⊙o⊙)…好像Java里面的new有木有,然而不要这样想,他们完全不是同一个东东,如果你不知道Java中的new请放心食用。
我们从一定的场景带入,一步一步接近new的真相。
想象我们置身于骑砍 `<_` 的世界中,已经有自己的兵营了,现在我们要自建自己的骑兵团队。 首先我们先捏一个骑兵出来:
var cavalry = { id: 1, // 用于区分每个士兵 type:'cavalry', // 士兵类型 damage:5, // 伤害值 HP:42, // 血量 riding:function(){ /*骑马*/}, attack:function(){ /*攻击*/ }, defense:function(){ /*防御*/ } }
当我们捏出一个骑兵后,我们要达到量产呀,这次我们训练出一百个骑兵来组成骑兵团队。
// 骑士团1.0 var knights = [] var cavalry for(var i =0; i < 100; i++){ cavalry = { id: i, // 用于区分每个士兵 type:'cavalry', // 士兵类型 damage:5, // 伤害值 HP:42, // 血量 riding:function(){ /*骑马*/}, attack:function(){ /*攻击*/ }, defense:function(){ /*防御*/ } } knights.push(cavalry) } console.log(knights)
这样我们就得到了我们的骑士团了。 这里我们会发现一些问题:
那我们来改进一下我们的训练方式 我们这里可以通过JavaScript原型链去解决这个问题,如果你原型链还没搞定可以先虐杀原型,再来建立骑士团。
// 我们先来创建一个骑兵的原型 var _cavalry = { type:'cavalry', // 士兵类型 damage:5, // 伤害值 HP:42, // 血量 riding:function(){ /*骑马*/}, attack:function(){ /*攻击*/ }, defense:function(){ /*防御*/ } } // 骑士团2.0 var knights = [] var cavalry for(var i =0; i < 100; i++){ cavalry = { id: i, // 用于区分每个士兵 } // 将实例的__proto__指向_cavalry cavalry.__proto__ = _cavalry knights.push(cavalry) } console.log(knights)
吼啦,我们可以解决创建骑士团1.0的问题了,但是2.0整体代码我们还是可以改进一下的。
// 我们先来创建一个骑兵的原型 var _cavalry = { type:'cavalry', // 士兵类型 damage:5, // 伤害值 HP:42, // 血量 riding:function(){ /*骑马*/}, attack:function(){ /*攻击*/ }, defense:function(){ /*防御*/ } } function cavalryFactory (id) { // 创建骑兵的兵工厂 var cavalry = {} cavalry.__proto__ = _cavalry cavalry.id = id return cavalry } // 骑士团3.0 var knights = [] for(var i =0; i < 100; i++){ knights.push(cavalryFactory(i)) } console.log(knights)
这样我们骑士团3.0看起来是不是高大上了很多呢
简单来讲这里cavalryFactory骑兵工厂发挥的作用和我们new运算符的作用就已经很接近啦,那我们就来模拟实现一个真正的new运算符吧。
在模拟之前,我们先看看使用new运算符如何去创建我们的骑士团。
// 骑兵的构造函数 var Cavalry = function(id){ this.id = id } // 设置原型属性 Cavalry.prototype.type = 'cavalry' Cavalry.prototype.damage = 5 Cavalry.prototype.HP = 42 Cavalry.prototype.riding = function(){ /*骑马*/} Cavalry.prototype.attack = function(){ /*攻击*/} Cavalry.prototype.defense = function(){ /*防御*/} // 骑士团 var knights = [] for(var i =0; i < 100; i++){ knights.push(new Cavalry(i)) } console.log(knights)
我们有了骑士团3.0的经验,我们再结合原型链相关知识我们可以很轻松的模拟出第一版objFactory
objFactory
function objFactory(){ // 初始化一个临时对象 var obj = new Object() // 获取第一个参数为构造函数,shift会改变原数组哦 var Construct = [].shift.call(arguments) // 将临时对象的原型指向构造函数的prototype obj.__proto__ = Construct.prototype // 使用apply给obj添加属性 Construct.apply(obj, arguments) return obj } function Cavalry (id) { this.id = id } Cavalry.prototype.type = 'cavalry' Cavalry.prototype.damage = 5 Cavalry.prototype.HP = 42 Cavalry.prototype.riding = function(){ /*骑马*/} Cavalry.prototype.attack = function(){ /*攻击*/} Cavalry.prototype.defense = function(){ /*防御*/} // 骑士团4.0 var knights = [] for(var i =0; i < 100; i++){ knights.push(objFactory(Cavalry, i)) } console.log(knights)
额,在模拟过程中我们使用apply给临时obj添加了id属性和值,如果对apply功能有疑问可以猛戳JavaScript模拟实现call,apply,bind等方法 ( ´´ิ∀´ิ` )
这里我们观察骑士团4.0与我们使用new创建的骑士团其实已经没有什么区别了。
既然我们模拟new运算符的实现,我们再考虑下构造函数有返回值的情况,先来看一个示例:
function Cavalry(id, type){ this.id = id this.type = type this.HP = 42 return { id } } var cavalry = new Cavalry(1, 'cavalry'); console.log(cavalry.id) // 1 console.log(cavalry.type) // undefined console.log(cavalry.HP) // undefined
可以发现当构造函数返回一个对象时,我们的实例对象cavalry只能访问到返回对象中的属性值。
那么当返回一个基本类型时会是什么情况呢?
function Cavalry(id, type){ this.type = type this.HP = 42 return 'i am cavalry' } var cavalry = new Cavalry(1, 'cavalry'); console.log(cavalry.id) // undefined console.log(cavalry.type) // cavalry console.log(cavalry.HP) // 42
从返回结果我们可以发现,当返回基本类型时,此时的处理相当于没有返回值时的处理。
那么我们需要判断下构造函数的返回值是一个object还是基本类型,这里我来改进下终极版objFactory:
function objFactory(){ // 初始化一个临时对象 var obj = new Object() // 获取第一个参数为构造函数,shift会改变原数组哦 var Construct = [].shift.call(arguments) // 将临时对象的原型指向构造函数的prototype obj.__proto__ = Construct.prototype // 使用apply给obj添加属性 var result = Construct.apply(obj, arguments) return (typeof result === 'object' && result !== null) ? result : obj }
参考文章: JS 的 new 到底是干什么的? JavaScript深入之new的模拟实现
若文中有知识整理错误或遗漏的地方请务必指出,非常感谢。如果对你有一丢丢帮助或引起你的思考,可以点赞鼓励一下作者=^_^=
The text was updated successfully, but these errors were encountered:
No branches or pull requests
https://wolfdu.fun/post?postId=5a473e9a25322c62a62e7b15
new运算符:
(⊙o⊙)…好像Java里面的new有木有,然而不要这样想,他们完全不是同一个东东,如果你不知道Java中的new请放心食用。
我们从一定的场景带入,一步一步接近new的真相。
想象我们置身于骑砍 `<_` 的世界中,已经有自己的兵营了,现在我们要自建自己的骑兵团队。
首先我们先捏一个骑兵出来:
我的骑兵我的团↖(▔^▔)↗
当我们捏出一个骑兵后,我们要达到量产呀,这次我们训练出一百个骑兵来组成骑兵团队。
这样我们就得到了我们的骑士团了。
这里我们会发现一些问题:
那我们来改进一下我们的训练方式
我们这里可以通过JavaScript原型链去解决这个问题,如果你原型链还没搞定可以先虐杀原型,再来建立骑士团。
吼啦,我们可以解决创建骑士团1.0的问题了,但是2.0整体代码我们还是可以改进一下的。
这样我们骑士团3.0看起来是不是高大上了很多呢
简单来讲这里cavalryFactory骑兵工厂发挥的作用和我们new运算符的作用就已经很接近啦,那我们就来模拟实现一个真正的new运算符吧。
模拟实现new运算符
在模拟之前,我们先看看使用new运算符如何去创建我们的骑士团。
我们有了骑士团3.0的经验,我们再结合原型链相关知识我们可以很轻松的模拟出第一版
objFactory
额,在模拟过程中我们使用apply给临时obj添加了id属性和值,如果对apply功能有疑问可以猛戳JavaScript模拟实现call,apply,bind等方法 ( ´´ิ∀´ิ` )
这里我们观察骑士团4.0与我们使用new创建的骑士团其实已经没有什么区别了。
模拟构造函数返回值
既然我们模拟new运算符的实现,我们再考虑下构造函数有返回值的情况,先来看一个示例:
可以发现当构造函数返回一个对象时,我们的实例对象cavalry只能访问到返回对象中的属性值。
那么当返回一个基本类型时会是什么情况呢?
从返回结果我们可以发现,当返回基本类型时,此时的处理相当于没有返回值时的处理。
那么我们需要判断下构造函数的返回值是一个object还是基本类型,这里我来改进下终极版
objFactory
:小结下
参考文章:
JS 的 new 到底是干什么的?
JavaScript深入之new的模拟实现
若文中有知识整理错误或遗漏的地方请务必指出,非常感谢。如果对你有一丢丢帮助或引起你的思考,可以点赞鼓励一下作者=^_^=
The text was updated successfully, but these errors were encountered: