Javascript Расширение базовых типов (наследование прототипа)
Я только начал читать о Дугласе Крокфорде "Javascript The Good parts", где он объясняет об увеличении основных типов.
Function.prototype.addMethod=function(name,func) {
this.prototype[name]=func;
return this;
};
Момент после этого, addMethod становится доступным для всех основных объектов, таких как String, Number и т.д. Это оставляет меня озадаченным
[1] Почему это происходит, когда я не добавил его в Object.prototype?
[2] Почему добавление метода к Function.prototype находит отражение во всех основных объектах?
Я новичок в javascript и прототипном наследовании. Поэтому я действительно не знаю, глупы ли мои вопросы?
Ответы
Ответ 1
Вероятно, он имел в виду. После выполнения этого метода addMethod становится доступным для всех базовых объектов типов объектов, таких как String, Number и т.д. Это связано с тем, что объект String является (но объекты, созданные String, не являются).
Например, данный
var s = '';
Вы можете сделать
String.addMethod(...);
но не
s.addMethod(...);
Ниже приводится краткое описание системы типа JavaScript:
В JavaScript нет нормального понятия классов. Вместо этого вы можете добиться того же, превратив любую функцию в конструктор путем puttin ключевое слово new перед ним, когда оно вызывается.
Например: данный
function MyFunction(x) { this.myX = x; }
если вы вызываете его как
var myObj = new MyFunction(10);
он создаст объект с именем myObj. Этот объект будет иметь одну переменную-член, называемую myX. Функция MyFunction считается конструктором объекта (и сохраняется в свойстве "конструктор".
(Бонусный вопрос: что произойдет, если вы вызовете функцию выше без нового ключевого слова, т.е. var x = MyFunction(10)
. Ответ, вероятно, удивит любого разумного человека.)
Теперь вы видели, как любая произвольная функция может быть преобразована в конструктор. Встроенные объекты точно такие же, строковые объекты создаются функцией String, числа создаются функцией Number и т.д.
Так же, как эти встроенные объекты создаются функциями, каждая из этих функций также создается функцией "Функция" (yikes!).
Теперь о прототипах.
в приведенном выше примере, если вы где-нибудь пишете
MyFunction.prototype.someNewMethod = function() {}
все объекты, созданные конструктором/функцией MyFunction, будут иметь дополнительную функцию-член, называемую someNewMethod. Вы можете делать много других фанковых вещей с прототипами, например, заменять прототип или заменять прототип прототипа, но я не эксперт в этом.
Ответ 2
В объектно-ориентированном javascript функция может служить как класс и конструктор. Поэтому, если ваш класс был назван MyObject, вы можете сделать следующее:
// create a class/constructor
function MyObject() {
// ...
}
// add a static method to the MyObject class
MyObject.someFunction = function() {
// ...
}
// add an instance method to the MyObject Class
MyObject.prototype.someFunction = function() {
// ...
}
В вашем примере addMethod был добавлен как метод экземпляра в класс Function, что означает, что он доступен для всех экземпляров Function. Функция MyObject/class/constructor является экземпляром Function, поэтому вы можете вызвать addMethod на нем. Это работает с большинством любых типов объектов, но не с HTMLElements в IE и некоторых других браузерах.
Ответ 3
-
Функции в JavaScript - это объекты. Все объекты имеют скрытую ссылку
to Object.prototype. Таким образом, для первого объявления:
> `Function.prototype.addMethod=function(name,func) {}
Вы объявили функцию, связанную с Function.prototype, которая сама связана с Object.prototype.
- Для второй части это просто назначение, в котором вы устанавливаете пару значений имени в Object.prototype и вернете метод добавления ко всем объектам String, Number, поскольку все они объявлены в прототипе.