JS | 改变 this 指向 | this 指向 null 为什么不影响原型链?
省流总结:this,只影响函数执行时 this 的值
概念 | 说明 |
---|---|
this 绑定 | 影响函数运行时内部 this 的指向(比如函数调用时谁是 this) |
prototype 链接 | 影响通过 new 调用时实例的原型链结构 |
背景:调用 函数.bind(null) ,将函数的 this 指向 null。为何这里的 this 不影响原型链?——》 this,只影响函数执行时 this 的值
分析【知识点汇总】:
区分两个完全不同的概念:
概念 | 说明 |
---|---|
this 绑定 | 影响函数运行时内部 this 的指向(比如函数调用时谁是 this) |
prototype 链接 | 影响通过 new 调用时实例的原型链结构 |
在这里:
bind(null, 'Suna')
中的null
只是说:const BoundPerson = Person.bind(null, 'Suna');
当 直接调用
BoundPerson()
时(不是new
调用),内部函数里的this
会被绑定到Object(null)
(即全局对象);而
.prototype
这部分逻辑是myBind
函数内部写死的,与传入的objThis
无关。
所以 objThis
(即 null
)只影响函数执行时 this 的值,
不会影响 BoundPerson.prototype
如何被设置。
原例子
myBind是 手动实现 bind 绑定 this
Function.prototype.myBind = function(objThis, ...params) {const thisFn = this; // ← 注意:此时 this 就是调用 bind 的函数,也就是 Personlet funcForBind = function(...secondParams) {const isNew = this instanceof funcForBind;const thisArg = isNew ? this : Object(objThis);return thisFn.call(thisArg, ...params, ...secondParams);};// ⬇️关键语句在这里funcForBind.prototype = Object.create(thisFn.prototype);return funcForBind;
};
举例验证 myBind 的 bind 绑定情况 代码:
function Person(name) {this.name = name;
}
Person.prototype.sayHi = function() {console.log('hi, I am ' + this.name);
}const BoundPerson = Person.myBind(null, 'Suna');
const p = new BoundPerson();p.sayHi(); // ✅ hi, I am Suna
console.log(p instanceof Person); // ✅ true
console.log(p instanceof BoundPerson); // ✅ true
验证得出:BoundPerson.prototype.__proto__ === Person.prototype
提问:为什么const BoundPerson = Person.myBind(null, 'Suna'); ,这里将Person的this指向null,将其结果赋值给BoundPerson,为什么就可以推出 BoundPerson.prototype.__proto__ = Person.prototype?
分析 —— 调用时的具体代入
调用:
const BoundPerson = Person.myBind(null, 'Suna');
逐步推理:
这里
this
是Person
,所以:thisFn = Person
创建了一个新函数:
funcForBind = function(...secondParams) { ... }
执行了关键的语句:
funcForBind.prototype = Object.create(thisFn.prototype); // 即: funcForBind.prototype = Object.create(Person.prototype);
然后返回:
return funcForBind;
于是:
const BoundPerson = funcForBind;
这意味着什么?
我们可以直接展开:
BoundPerson.prototype = Object.create(Person.prototype);
根据 Object.create
的语义:
Object.create(Person.prototype)
创建了一个新对象,它的 __proto__
指向 Person.prototype
。
所以:
BoundPerson.prototype.__proto__ === Person.prototype
总结:
BoundPerson.prototype = Object.create(Person.prototype);
BoundPerson.prototype.__proto__ === Person.prototype