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 уже появляется на самом внешнем уровне?
классно.........!



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


var Foo = function(){};
Определена новая функция с именем - Foo. Если мы воспользуемся console.dir(Foo), мы увидим, что Foo имеет 2 специальных члена: prototype и __proto__.
Object.defineProperty(Foo.prototype,'x',{
get(){
return 3;
}
});
Обновлен прототип Foo. О defineProperty (от MDN):
The static method Object.defineProperty() defines a new property directly 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 и применяется геттер x
Расширение 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 и почему это происходит
Это происходит потому, что в 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;
}
});
}
«вы используете объект Foo.prototype (как функцию)» - нет? И это даже невозможно, так как Foo.prototype не является функцией!
Foo.__proto__ - это просто Function.prototype. Как вы сказали, добавление свойств не повлияет на объекты, созданные из Foo, но вы, похоже, упустили, что это повлияет на каждую отдельную функцию. После расширения Foo.__proto__ попробуйте console.info(function(){}.x);
Похоже,
console.dirзапутался. Это ошибка.xне является собственностьюfoo.