Object.getOwnPropertyNames中的混淆

时间:2015-04-13 06:20:20

标签: javascript

您好以下代码



   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);




我得到的结果是构造函数,作业,项目,显示

我的问题是为什么我没有在第一个案例的结果中得到构造函数?

2 个答案:

答案 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 }); 之后。否则它将被重写。

更多阅读:http://javascript.info/tutorial/constructor

https://codereview.stackexchange.com/questions/62402/javascript-constructor-and-namespace-in-object-literal-style/86222#86222