var Foo = function(){};
Object.defineProperty(Foo.prototype,'x',{
get(){
return 3;
}
});
var foo = new Foo();
console.dir(foo);
我想要的结果应该是
Foo {
__proto__:{
constructor: ƒ (),
x: 3,
__proto__: Object
}
}
但是真正的结果是
Foo {
x: 3,
__proto__:{
constructor: ƒ (),
x: 3,
__proto__: Object
}
}
为什么x属性已经出现在最外层?
答案 0 :(得分:-2)
var Foo = function(){};
定义了一个新函数,名为-Foo。如果我们使用console.dir(Foo)
,我们将看到Foo
有2个特殊成员prototype
和__proto__
Object.defineProperty(Foo.prototype,'x',{
get(){
return 3;
}
});
Foo的原型已更新。关于defineProperty
(来自MDN):
静态方法Object.defineProperty()定义了一个新属性 直接在对象上,或修改对象上的现有属性, 并返回对象。
因此prototype
对象现在被一个名为x
的新成员修改了。 prototype
在这里充当角色,并且在创建Foo
的新实例时将“启动”
var foo = new Foo();
创建了一个新的Foo实例。 c'tor调用使用的是Foo原型,并且应用了x
getter
扩展Foo prototype
,从而确保它仅影响从Foo
创建的对象(作为一个类)
Object.defineProperty(Foo.prototype, 'x',
{
get: () => 3
});
console.dir(new Foo().x) // will show 3
console.dir(Foo.x) // undefined - protorype is for class objects
或扩展Foo __proto__
,从而将Foo
作为函数进行更新,同时不影响由此创建的对象
Object.defineProperty(Foo.__proto__, 'x',
{
get: () => 3
});
console.dir(new Foo().x) // undefined - x is not a member of Foo
console.dir(Foo.x) // 3
奖金:关于JS原型及其发生原因的很好的article
之所以会这样,是因为在JS function
中,这是一种同时声明函数和类的方法!
因此,您的Foo
函数也可以用作类
var Foo = function(){};
Foo(); // call Foo as a function
var obj = new Foo(); // initiate an instance from class Foo
因为您正在使用Foo.prototype
对象(作为函数),然后从Foo
类创建新实例,所以可以保证:
我真的认为您的代码应该是这样的:
function Foo ()
{
Object.defineProperty(this,'x',{
get(){
return 3;
}
});
}