Что случилось (пошагово)
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
здесь действует как c'tor и «стартует», когда будет создан новый экземпляр Foo
var foo = new Foo();
Создан новый экземпляр Foo.вызов c'tor использует прототип Foo и применяется x
getter
Alternatives
Extennding 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;
}
});
}