Подтвердить что ты не робот

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 и прототипном наследовании. Поэтому я действительно не знаю, глупы ли мои вопросы?

4b9b3361

Ответ 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, поскольку все они объявлены в прототипе.