gpt4 book ai didi

javascript - 为函数原型(prototype)调用 Object.defineProperty 时会发生什么?

转载 作者:搜寻专家 更新时间:2023-11-01 04:43:32 28 4
gpt4 key购买 nike

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属性已经出现在最外层了?

最佳答案

发生了什么(一步一步)

var Foo = function(){};

定义了一个新函数,命名为 - Foo。如果我们使用 console.dir(Foo) 我们会看到 Foo 有两个特殊成员 prototype__proto__

Object.defineProperty(Foo.prototype,'x',{
get(){
return 3;
}
});

更新了 Foo 的原型(prototype)。关于 defineProperty(来自 MDN):

The static method Object.defineProperty() defines a new propertydirectly on an object, or modifies an existing property on an object,and returns the object.

因此 prototype 对象现在被修改为一个名为 x 的新成员。 prototype 在这里作为一个 c'tor,当 Foo 的新实例被创建时将“启动”

var foo = new Foo();

一个新的 Foo 实例被创建。 c'tor 调用使用 Foo 原型(prototype)并且应用了 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

奖金:非常好 article关于 JS 原型(prototype)以及为什么会这样

原始答案

这是因为在 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 类创建一个新实例,您保证那:

  1. 您的函数原型(prototype)将使用您的新 getter 进行修改
  2. 来自您的类的每个新对象(继承)也将使用您的新 getter(在对象级别)

我真的认为你的代码应该是这样的:

function Foo ()
{
Object.defineProperty(this,'x',{
get(){
return 3;
}
});
}

关于javascript - 为函数原型(prototype)调用 Object.defineProperty 时会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53816004/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com