您好以下代码
function employee()
{
this.name="john";
}
employee.prototype={
job:"manager",
projects:["sales","training","construction"],
display:function()
{
alert(this.name+" is a "+ this.job);
}
}
var property=Object.getOwnPropertyNames(employee.prototype);
alert(property);

我得到的结果是工作,项目,显示,但是当我以这种方式使用原型定义属性时
function employee()
{
this.name="john";
}
employee.prototype.job="manager";
employee.prototype.projects=["sales","training","construction"];
employee.prototype.display=function()
{
alert(this.name+"is a"+ this.job);
}
var property=Object.getOwnPropertyNames(employee.prototype);
alert(property);

我得到的结果是构造函数,作业,项目,显示
我的问题是为什么我没有在第一个案例的结果中得到构造函数?
答案 0 :(得分:2)
当您声明employee
函数时,它会实例化一个Function实例,其prototype
包含指向该函数的“构造函数”属性。为原型分配新属性将保留该属性。因此,使用new employee
创建的对象将继承此“构造函数”属性,该属性将说明它们构造的内容。
function C(){}
console.log(C.prototype.constructor) // returns C
console.log(C.prototype.hasOwnProperty("constructor") // true
cosole.log(new C().constructor) // C
cosole.log(new C().hasOwnProperty("constructor") // false, it's inherited
但是,当您覆盖整个prototype
时,您还会删除constructor
属性。对象有一个构造函数(Object
)但是它是继承的,所以它不会显示为“OwnProperties”。
答案 1 :(得分:0)
将对象分配给原型时,它会更改该对象的原型继承。因为在第一个示例中,您将对象直接分配给原型,所以对象 本身 将被分配给原型。这将覆盖对象原型上的employee
构造函数,并将其替换为全局Object
对象。这是发生事情的关键。
您可以通过将此行代码放入第一个实现来验证构造函数是否被覆盖:
console.log(employee.prototype.constructor === Object); // returns: true
正如您所看到的,它会返回true
- 验证您employee.prototype
的构造函数不是您所期望的(它会自行设置... {{1} }),而是全局employee
对象。
由于构造函数现在设置为全局Object
,因此Object
方法无法在getOwnPropertyNames
对象属性中检索它。 employee
方法仅检索属于该对象本身的方法 - 不是继承的对象。
您可以通过添加一行来更正第一个代码段,如代码中所示:
getOwnProperyNames
重置对象原型的构造函数,现在它也将返回function employee() {
this.name = "john";
}
employee.prototype = {
constructor: employee, // <--- ADD THIS LINE
job: "manager",
projects: ["sales", "training", "construction"],
display: function() {
alert(this.name + " is a " + this.job);
}
};
var property = Object.getOwnPropertyNames(employee.prototype);
alert(property);
。
值得注意的是,以这种方式恢复构造函数会创建一个constructor
设置为enumerable
的属性。默认情况下,本机构造函数不可枚举。因此,如果您正在使用ES5,这可能是恢复构造函数的首选方法:
true
注意:此代码段必须放在Object.defineProperty(employee.prototype, 'constructor', {
enumerable: false,
value: employee
});
之后。否则它将被重写。