[JS] 先bind后new,this的指向

JavaScript016

[JS] 先bind后new,this的指向,第1张

非严格模式下,以下调用方式中, this 绑定为全局对象 window ,

而在严格模式下, this 绑定为 undefined 。

值得注意是的,只有 this 处于严格模式中,才会绑定为 undefined ,

与 f 被调用的位置是否处于严格模式无关。

可见 new 对 this 的影响比 bind 优先级要高,

g 虽然通过 bind 绑定了 this 指向的对象为 {a:1} ,

但是使用 new g 调用的时候, this 仍然指向以 f 为构造函数的实例。

值得注意的有两点,

(1) bind 之后, g.prototype 为 undefined 。

(2) new g 返回的对象 obj ,使用 instanceof 判断 f 和 g 都为 true ,

原因就在于, V instanceof target 首先会先用 target[Symbol.hasInstance](V) 来判断,

然后再判断, target.prototype 是否在 V 的原型链上,参考 ECMAScript Language Specification

但是 bind 的柯里化作用还是有用的,

使用 call 或者 apply ,将 this 绑定为 null 或 undefined 并不会凑效,

此时, this 将绑定为全局对象。

然而,在严格模式下, this 将绑定为 null 或 undefined ,

值得一提的是,在非严格模式下, f.call(1)会自动将 1 包装成 new Number(1) ,

然后 this 指向的是这个包装对象。

而在严格模式下, f.call(1)会将 this 绑定为 1 。

b={} 相当于 b=new Object ,因此, b 是 Object 构造函数的实例。

而 Object.create(null) 会创建一个空对象,它没有原型。

注意, Object.create(undefined)会报错,

赋值表达式的返回值是函数的引用,因此相当于 f() ,

而不是 obj1.f() ,也不是 obj2.f() 。

你不知道的JavaScript(上卷)

现在写一个函数,这个函数的返回值是一个对象,来观察一下这个对象,和函数体内this指向

①,对象a就是一个空对象

②,对象a没有color属性

③,对象a原型指向Object.prototype

④,函数体内this指向window(上图可见,没调用函数之前,window.color属性不存在)

在执行函数时,加一个new试试看有啥效果:

①,没有return,这个函数居然返回了一个对象

②,对象a有个color属性

③,对象a的原型指向了这个构造函数的prototype属性

④,window对象没有color属性

⑤,this指向了对象a

由上得出总结new的作用:

①,new能让一个构造函数返回一个对象(下面称为A)而无需return

②,new会让函数体内的this指向这个A

③,new会让A的原型指向这个构造函数的prototype属性

PS:

①,new只用了三个字符,却实现了很多功能,非常贴心,可以称呼new为语法糖或贴心语法( syntactic sugar )

②,一个函数自带prototype对象,而且里面默认有一个constructor属性,这个属性返回实例对象的构造函数,如果你重新给prototype对象赋值,小心不要覆盖掉它

③,如果使用new,函数内就别 return一个对象 了 ,这样返回的是return后面的对象,this不会指向它

④,就算函数体内空空如也,new的作用不变

new声明的是一个对象,而不是函数 而直接写函数,那就不是对象,是无法调用对象的属性的。如果不new,直接调用YourFunc,不做对象的初始化;如果new,先初始化一个对象,然后调用YourFunc作为初始化函数。初始化对象的时候,会把所有YourFunc.prototype的属性方法,copy一份给这个对象;意味着你在YourFunc里面如果调用this.a this.b this.c this.sayHello,都已经被初始化过一次了。