未重新赋值构造函数时如何使用new?原型继承constructor相关疑问
1. 未重新赋值构造函数时,怎么用new关键字调用函数?
这事儿超简单!你直接用new 函数名(参数)调用就行啦~JavaScript里的普通函数天生就有构造函数的能力,当你用new调用它时,JS引擎会自动帮你完成一系列操作:
- 创建一个空的新对象
- 把这个新对象的
__proto__指向函数的prototype属性(默认自带constructor指向函数本身) - 把函数内部的
this绑定到这个新对象上 - 执行函数体里的代码(比如给
this添加属性) - 如果函数没主动返回对象类型的值,就自动返回这个新对象
举个实际例子:
function Person(name) { this.name = name; } // 直接用new调用,完全没问题 const alice = new Person("Alice"); console.log(alice.name); // 输出 "Alice"
这里我们根本没碰过Person的prototype或constructor,照样能用new,因为函数默认的原型配置就满足构造函数的要求。
2. 原型继承示例里的两个小问题
先补全你给出的代码场景(应该是这样的原型赋值逻辑吧?):
let animal = { eats: true, hyponym: "Animal" }; function Rabbit(name) { this.name = name; // 默认情况下: // Rabbit.prototype = { constructor: Rabbit } } // 将Rabbit的原型改为animal,实现继承 Rabbit.prototype = animal;
跳过重新赋值constructor,怎么用new?
哪怕你没手动把Rabbit.prototype.constructor改回Rabbit,照样能正常用new Rabbit(...)调用!因为new关键字的工作逻辑根本不依赖prototype.constructor这个属性——它只认你当前调用的那个函数本身。比如:
const rabbit = new Rabbit("小白"); console.log(rabbit.name); // 输出 "小白" console.log(rabbit.eats); // 输出 true
完全正常运行对吧?只是这时候rabbit.constructor会指向Object(因为animal是普通对象,它的constructor默认是Object),但这丝毫不影响new的使用,也不影响实例的创建。
哪个构造函数设置了this.name?
当然是**Rabbit函数**啦!当你用new Rabbit("小白")时,JS引擎会把新创建的空对象绑定到Rabbit函数内部的this上,然后执行this.name = name这行代码,所以是Rabbit构造函数给实例设置了name属性。
至于你提到的“将原型改为其他对象时constructor会变为null”,可能是教程表述有点小偏差:实际如果是把原型改成普通对象(比如{}),它的constructor默认是Object;只有当原型是用Object.create(null)创建的无原型对象时,才没有constructor属性。但不管哪种情况,都不影响new调用构造函数,也不影响this的绑定。
内容的提问来源于stack exchange,提问作者Amit Shah

