#javascript
#javascript
Вопрос:
Хорошо, сначала я хотел бы сказать, что я знаю, что для этого, вероятно, есть очень простое объяснение, поэтому извините меня, если это слишком вопрос для новичков.
Вопрос в том, почему свойство Error.message не существует, пока я не создам новый прототип?
Пример:
let a = new Error('testing')
console.log( a.message ) // 'testing'
Но раньше, если бы я попытался получить доступ к свойствам и методам ошибки (например: Object.getOwnPropertyNames(Error)
), свойства message даже не было бы, даже пустой строки, оно просто не существовало бы.
Разве раньше это не должна была быть пустая строка? Как объект ошибки создает новое свойство самостоятельно при создании нового прототипа?
Комментарии:
1.
getOwnPropertyNames
возвращает только свойства, установленные для объекта, а не унаследованные (прототипные) свойства. Ключ к разгадке кроется в названии: » own «-properties .2. Что вы подразумеваете под » когда создается новый прототип «?
3.
Object.getOwnPropertyNames(Error)
будет перечисляться только статические члены функцииError
конструктора. Если вы это сделаетеObject.getOwnPropertyNames( Error.prototype )
, вы увидите thme.4. Как вы думаете
const a = {message: "testing"}
, как создается новое свойство для нового объекта без свойства, существующего в каком-либо прототипе ранее?
Ответ №1:
getOwnPropertyNames
возвращает только свойства, установленные для объекта, а не унаследованные (прототипные) свойства. Ключ к разгадке кроется в названии: «own«-properties .
На примере:
const a_simple_object_with_no_prototype = {
b: "b",
c: "c"
};
console.log( Object.getOwnPropertyNames( a_simple_object_with_no_prototype ) )
// [ "b", "c" ]
С объектом со свойствами, унаследованными от прототипа, мы получаем разные результаты:
const an_object_used_as_a_prototype = {
a: 789
};
function ConstructorFunction() {
this.b = "b";
}
ConstructorFunction.prototype = an_object_used_as_a_prototype;
const an_object_with_a_prototype = new ConstructorFunction();
an_object_with_a_prototype.c = "c";
console.log( Object.getOwnPropertyNames( an_object_with_a_prototype ) )
// [ "b", "c" ] // does not include "a" which is inherited from the prototype
Но раньше, если бы я попытался получить доступ к свойствам и методам ошибки (например:
Object.getOwnPropertyNames(Error)
), свойства message даже не было бы, даже пустой строки, оно просто не существовало бы.
Это потому Object.getOwnPropertyNames(Error)
, что будут перечислены только «статические» 1 члены функции Error
конструктора. Если вы это сделаете Object.getOwnPropertyNames( Error.prototype )
, вы их увидите:
const protoProps = Object.getOwnPropertyNames( Error.prototype );
console.log( protoProps ); // ["constructor", "name", "message", "toString"]
Я отмечаю, что Error
объект в JavScript обладает некоторым особым поведением, которое вы не можете воспроизвести в самом JavaScript, например, как stack
работает его свойство, но это выходит за рамки вашего вопроса.
1: Я использую термин «статический» в смысле C / Java / C # в том смысле, что это поле / элемент, который связан с типом, а не с экземпляром. Это не означает, что свойство / поле / элемент является неизменным, доступным только для чтения или неизменяемым.