使用bind绑定构造函数后创建对象丢失age属性的原因
为什么用bind绑定构造函数的this后,new创建的对象丢失了绑定的属性?
先看你给出的代码:
"use strict"; let Person = function(name){ this.name = name; } let age = { age: 128 } let AgedPerson = Person.bind(age) console.log(new AgedPerson("John"))
你预期输出:
{ age: 128, name: "John" }
实际得到:
{ name: "John" }
核心原因
new操作符会完全忽略构造函数通过bind绑定的this上下文,这是JavaScript的规范规定的行为。
当执行new AgedPerson("John")时,JS引擎的执行逻辑是:
- 创建一个全新的空对象;
- 把这个空对象的原型指向
AgedPerson.prototype(也就是原Person.prototype); - 将这个空对象作为
this,调用构造函数Person; - 如果构造函数没有返回对象类型的值,就返回这个新创建的对象。
整个过程里,你用bind指定的age对象完全没参与构造流程,构造函数里的this.name = name只是给新创建的空对象赋值,自然不会带上age的属性。
实现预期效果的几种方式
方法1:构造函数内手动合并属性
直接在构造函数里把age的属性合并到新对象上:
"use strict"; let Person = function(name){ Object.assign(this, age); // 合并age的属性到当前实例 this.name = name; } let age = { age: 128 } console.log(new Person("John")); // {age: 128, name: "John"}
方法2:挂载属性到构造函数原型
把age的属性放到构造函数的原型上,让所有实例继承该属性:
"use strict"; let Person = function(name){ this.name = name; } let age = { age: 128 } // 合并属性到原型 Object.assign(Person.prototype, age); const instance = new Person("John"); console.log(instance.name); // "John" console.log(instance.age); // 128(从原型链读取)
方法3:用Object.create实现继承
让新实例继承age对象,再执行构造函数逻辑:
"use strict"; let Person = function(name){ this.name = name; } let age = { age: 128 } let AgedPerson = function(name) { // 创建继承自age的对象 const obj = Object.create(age); // 用该对象作为this执行Person构造逻辑 Person.call(obj, name); return obj; } console.log(new AgedPerson("John")); // {name: "John", __proto__: {age: 128}}
内容的提问来源于stack exchange,提问作者Some Name
相关产品推荐
相关产品推荐

