JavaScript构造函数详解:原理、注意事项与原型链修正
本文详细解析JavaScript构造函数的运行机制,包括new操作符的作用、返回值处理及this指向问题。重点探讨使用对象字面量重写原型对象时导致的constructor属性丢失问题,并提供手动重置constructor的解决方案,确保原型链完整性。
构造函数基本原理
构造函数的主要作用是初始化实例对象,而对象的prototype属性则用于继承自另一个实例对象。
构造函数注意事项
在使用构造函数时,需要注意以下几个关键点:
1. 按照惯例,构造函数名称的首字母应当大写。
2. 构造函数本身并不显式返回任何值。当使用new操作符调用构造函数时,JavaScript引擎会自动创建指定类型的实例并返回该实例。此时,构造函数内部的this对象会被自动创建,其类型即为构造函数的类型。
3. 构造函数内部也可以显式调用return语句。如果返回的是一个对象,则该对象会替代新创建的实例被返回;如果返回的是原始类型值,则该返回值会被忽略,新创建的实例仍会被返回。
function Person( name){
this.name =name;
}
var p1=new Person('John');
这一行为等同于以下逻辑:
function person(name ){
Object obj =new Object();
obj.name =name;
return obj;
}
var p1= person("John");
4. 由于构造函数本质上也是函数,因此可以直接调用(不使用new)。此时返回值为undefined,且构造函数内部的this对象指向全局this对象(在浏览器中为window)。这意味着this.name实际上是在创建一个全局变量name。如果在严格模式下直接调用Person构造函数(不使用new),将会抛出错误。

5. 也可以在构造函数中使用Object.defineProperty()方法来初始化属性:
function Person( name){
Object.defineProperty(this, "name"{
get :function(){
return name;
},
set:function (newName){
name =newName;
},
enumerable :true, //可枚举,默认为false
configurable:true //可配置
});
}
var p1=new Person('John');
原型对象与方法定义
6. 在构造函数中利用原型对象(prototype)来定义方法。
//比直接在构造函数中写的效率要高的多
Person.prototype.sayName= function(){
console.log(this.name);
};
然而,当需要定义的方法较多时,开发者通常倾向于采用更简洁的方式:直接使用对象字面量来替换整个原型对象,示例如下:
Person.prototype ={
sayName :function(){
console.log(this.name);
},
toString :function(){
return "[Person "+ this.name+"]" ;
}
};
原型重写与constructor修正
这种方式非常流行,因为它避免了多次键入Person.prototype。但需要注意一个副作用:

使用字面量形式重写原型对象会改变构造函数的constructor属性,使其指向Object而非Person。这是因为原型对象默认具有一个constructor属性,这是其他对象实例所不具备的。当函数被创建时,其prototype属性也被创建,且该原型对象的constructor属性指向该函数。当使用对象字面量重写原型对象时,其constructor属性将被重置为通用对象Object。为了避免这一问题,需要在重写原型对象时手动重置constructor,如下所示:
Person.prototype ={
constructor :Person,
sayName :function(){
console.log(this.name);
},
toString :function(){
return "[Person "+ this.name+"]" ;
}
};
再次进行测试验证:
p1.constructor===Person
true
p1.constructor===Object
false
p1 instanceof Person
true
什么时候该用JS构造器:与工厂模式、字面量的选择对比
2026-11-05 16:18:22
推荐几款轻量级JS照片墙开源库及对比
2026-11-05 15:56:19
JavaScript递归写法有哪些常见陷阱及避免方法
2026-11-05 14:53:38
JS数组浅拷贝与深拷贝怎么选?场景与方法总结
2026-11-05 14:41:02
p5.js 中 setup() 和 draw() 函数的执行机制详解
2026-11-05 12:32:38
