Как объект ошибки, по-видимому, создает свойства для себя самостоятельно на Javascript?

#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 # в том смысле, что это поле / элемент, который связан с типом, а не с экземпляром. Это не означает, что свойство / поле / элемент является неизменным, доступным только для чтения или неизменяемым.