Когда Вы осуществляете доступ к свойству объекта, JavaScript выполняет следующие шаги, как уже было описано в этой главе ранее:
Результат выполнения этих шагов зависит от того, как Вы выполняете определения. Оригинал примера имел такие определения:
function Employee () {
this.name = "";
this.dept = "general";
}
function WorkerBee () {
this.projects = [];
}
WorkerBee.prototype = new Employee;
Имея эти определения, создадим amy как экземпляр объекта WorkerBee следующим оператором:
amy = new WorkerBee;
Объект amy имеет одно локальное свойство, projects. Значения свойств name и dept не являются локальными для amy и поэтому получены из свойства __proto__ объекта amy. Таким образом, amy имеет следующие значения свойств:
amy.name == "";
amy.dept = "general";
amy.projects == [];
Теперь предположим, что Вы изменили значение свойства name в прототипе, ассоциированном с Employee:
Employee.prototype.name = "Unknown"
На первый взгляд, можно ожидать, что новое значение будет распространено на все экземпляры Employee, однако это не так.
Если Вы создаёте любой экземпляр объекта Employee, этот экземпляр получает локальное значение свойства name (пустую строку). Это означает, что, если Вы устанавливаете прототип WorkerBee через создание нового Employee-объекта, WorkerBee.prototype имеет локальное значение для свойства name. Следовательно, когда JavaScript видит свойство name объекта amy (экземпляра WorkerBee), JavaScript находит локальное значение этого свойства в WorkerBee.prototype. Он, следовательно, не просматривает далее цепь Employee.prototype.
Если Вы хотите изменить значение свойства объекта на этапе прогона программы и имеете новое значение, наследуемое всеми потомками объекта, Вы не можете определить это свойство в конструкторе функции объекта. Вместо этого Вы добавляете его к ассоциированному с конструктором прототипу. Например, предположим, Вы изменяете предыдущий код таким образом:
function Employee () {
this.dept = "general";
}
Employee.prototype.name = "";
function WorkerBee () {
this.projects = [];
}
WorkerBee.prototype = new Employee;
amy = new WorkerBee;
Employee.prototype.name = "Unknown";
В этом случае свойство name объекта amy стало "Unknown".
Как показывают все эти примеры, если Вы хотите иметь значения по умолчанию для свойств объекта и иметь возможность изменять эти значения по умолчанию на этапе прогона программы, Вы должны установить свойства прототипа конструктора, а не сам конструктор функции.