1. JS中的new关键字做了什么?
先说结论:
-
new是JS语言的设计核心,以new为中心衍生出了几个JS核心概念:this、原型等;
-
new是为了节约内存和代码量而创建的语法糖;
-
new帮我们把对象的共有属性放在原型里,实现了绑定原型;
-
new帮我们把对象的自身属性放在自己的构造函数里,执行构造函数;
-
new帮我们指定了this= 临时对象,创建了临时对象,并返回临时对象。
举个游戏中创建Soldier的栗子:
let soldier = {
ID:1,
kind:American GI,
attack:8,
hp:56,
move:function(){},
run:function(){},
attact:function(){},
defence:function(){}
}
Camp.construct(soldier)
function soldier(ID){
let 临时对象 = {} // new 创建临时对象
临时对象.__proto__ = sodier.原型 // new 绑定原型
临时对象.ID = ID
临时对象.hp = 56
return 临时对象 // new 帮我们return
}
soldier.原型 = {
kind:American GI,
attack:8,
hp:56,
move:function(){},
run:function(){},
attact:function(){},
defence:function(){}
}
- 用
new来写:
function solider(ID){
this.ID = ID
this.hp = 56
}
solider.prototype = {
kind:American GI,
attack:8,
hp:56,
move:function(){},
run:function(){},
attact:function(){},
defence:function(){}
}
- 创建
solider
let soliders = []
for(var i=0; i<100; i++){
soliders.push(new solider(i))
}
Camp.construct(soldiers)
- 再看字面量定义数组
a = []
a = new Array()
2. JS中的this是什么?
先说结论:
this就是call函数的第一个传入参数
从函数的三种调用形式说起:
f(p1, p2)
obj.child.method(p1, p2)
func.call(context, p1, p2) // 正常调用形式,其余上面2种是他的语法糖
- 分别把上面两行代码做转换后:
f.call(undefined, p1,p2)
本例中的undefined是f.call函数的第一个传入参数,即为this,同时浏览器发现this是undefined就会转成window
- 再举个栗子
obj.child.say()
本例中的假如obj是一个对象,child是他的一个属性,其属性名为child,其属性值存的一个地址#404,这个地址指向另一个对象,这个对象有一个属性,其属性名为say,其属性值存的另一个地址#505,这个地址指向另一个函数对象。
综上,函数对象是不属于obj或obj.child对象的,正因为函数和对象是没有任何关系的,所以需要把这个对象传给函数,如果不传参数,函数就不知道是哪个对象调用它,需要接收obj.child这个传入参数,函数在调用时得知道是哪个对象存着它,f.call(obj.child)
3. JS中的原型链是什么?
- 要解释原型链,需要先说明一下原型,举个栗子:
假设有一个普通对象x={ },这个x会有一个隐藏属性y,这个y会指向Object.prototype,即x.y = Object.prototype,x的原型是Object.prototype
y的唯一作用就是用来指向x的原型的,若没有y,x就不知道自己的原型是谁了
- 接下来说一说原型链,再举个栗子:
假设有一个数组对象a=[],这个a会有一个隐藏属性y,这个y会指向Array.prototype,即a.y=Array.prototype,a的原型是Array.prototype
与上例普通对象x是一样的,但是不一样的是a的原型Array.prototype也有一个隐藏属性z,指向Object.prototype,即Array.prototype.z=Object.prototype 这样一来,a就有两层原型:
a的原型是Array.prototype;a的原型的原型是Object.prototype,于是就通过隐藏属性z形成了一个链条,这就是原型链。
a ==> Array.prototype ==> Object.prototype
原型链解决了在没有class类的情况下,实现继承。
参考
jirengu.com