Прототип JavaScript (Prototype Object)

В JavaScript прототип — очень важная концепция, которая предоставляет объектам механизм наследования и общих свойств. У каждого объекта JavaScript есть связанный объект-прототип. Через объект-прототип можно совместно использовать свойства и методы, тем самым уменьшая использование памяти.

Все объекты JavaScript наследуют свойства и методы от прототипа (объекта-прототипа).

  • Прототип— это объект, который служит шаблоном или чертежом для других объектов.
  • Когда объект пытается получить доступ к свойству или методу, если он не найден в самом объекте, JavaScript будет искать по цепочке прототипов, пока не найдёт соответствующее свойство или метод, или не достигнет вершины цепочки прототиповnullи останавливается на этом.

Свойство __proto__ объектов

Каждый объект JavaScript (кроме null) автоматически имеет скрытое свойство __proto__, которое указывает на объект-прототип. Этот __proto__ — ключ к реализации наследования:

let obj = {};
console.log(obj.__proto__); // 输出: [object Object], 即 obj 的原型是 Object.prototype

Конструктор и прототип

В предыдущих главах мы узнали, как использовать конструктор объектов:

Пример

function Person(first, last, age, eyecolor) { this.firstName = first; this.lastName = last; this.age = age; this.eyeColor = eyecolor; } var myFather = new Person("John", "Doe", 50, "blue"); var my = new Person("Sally", "Rally", 48, "green");

Попробуйте сами »

Мы также знаем, что нельзя добавить новые свойства к объекту, у которого уже есть конструктор:

Пример

Person.nationality = "English";

Попробуйте сами »

Чтобы добавить новое свойство, нужно добавить его в функцию-конструктор:

Пример

function Person(first, last, age, eyecolor) { this.firstName = first; this.lastName = last; this.age = age; this.eyeColor = eyecolor; this.nationality = "English"; }

Попробуйте сами »

Когда вы создаете объект с помощью функции-конструктора, свойствоprototypeконструктора становится прототипом всех экземпляров объектов, созданных этой функцией-конструктором.

Пример

function Person(name) {
    this.name = name;
}

Person.prototype.sayHello = function() {
    console.log("Hello, my name is " + this.name);
};

let alice = new Person("Alice");
alice.sayHello(); // Вывод: Hello, my name is Alice

В этом примере Person.prototype является прототипом объекта alice, поэтому alice может получить доступ к методу sayHello.


Цепочка прототипов

В JavaScript объекты реализуют наследование через цепочку прототипов. Когда объект пытается получить доступ к свойству или методу, JavaScript сначала проверяет, есть ли это свойство или метод у самого объекта. Если нет, он ищет по цепочке прототипов.

let obj = {};
console.log(obj.toString()); // 输出: [object Object]
// 这个 `toString` 方法实际上是从 `Object.prototype` 继承过来的

В примере выше объект obj не определяет метод toString, поэтому JavaScript ищет по цепочке прототипов и в конечном итоге находит метод в Object.prototype.


Изменение прототипа

Вы можете динамически изменять прототип объекта, что может повлиять на все объекты, созданные на основе этого прототипа:

Пример

function Person(name) {
    this.name = name;
}

Person.prototype.sayHello = function() {
    console.log("Hello, my name is " + this.name);
};

let bob = new Person("Bob");
bob.sayHello(); // Вывод: Hello, my name is Bob

// Изменить прототип
Person.prototype.sayGoodbye = function() {
    console.log("Goodbye from " + this.name);
};

bob.sayGoodbye(); // Вывод: Goodbye from Bob

В этом примере мы добавили новый метод sayGoodbye в Person.prototype, и объект bob может сразу получить доступ к этому новому методу.


Метод Object.create

Метод Object.create позволяет создать новый объект и задать в качестве его прототипа указанный объект.

Пример

let personPrototype = {
    sayHello: function() {
        console.log("Hello, my name is " + this.name);
    }
};

let alice = Object.create(personPrototype);
alice.name = "Alice";
alice.sayHello(); // Вывод: Hello, my name is Alice

В этом примере прототипом alice является personPrototype, поэтому объект alice может получить доступ к методу sayHello.


Прототипное наследование

Все объекты JavaScript наследуют свойства и методы от прототипа (объекта-прототипа):

  • DateОбъекты изDate.prototypeнаследуют.
  • ArrayОбъекты изArray.prototypeнаследуют.
  • PersonОбъекты изPerson.prototypeнаследуют.

Все объекты в JavaScript являются экземплярами Object, который находится на вершине цепочки прототипов.

Объекты JavaScript имеют цепочку, указывающую на объект-прототип. При попытке доступа к свойству объекта поиск осуществляется не только в самом объекте, но и в его прототипе, и в прототипе этого прототипа, и так далее, слой за слоем вверх, пока не будет найдено свойство с совпадающим именем или пока не будет достигнут конец цепочки прототипов.

DateОбъекты,ArrayОбъекты, иPersonобъекты изObject.prototypeнаследуют.

Добавление свойств и методов

Иногда мы хотим добавить новые свойства или методы всем существующим объектам.

Кроме того, иногда мы хотим добавить свойства или методы в конструктор объекта.

Используя свойство prototype, можно добавить новые свойства в конструктор объекта:

Пример

function Person(first, last, age, eyecolor) { this.firstName = first; this.lastName = last; this.age = age; this.eyeColor = eyecolor; } Person.prototype.nationality = "English";

Попробуйте сами »

Конечно, мы также можем использовать свойство prototype, чтобы добавить новые методы в конструктор объекта:

Пример

function Person(first, last, age, eyecolor) { this.firstName = first; this.lastName = last; this.age = age; this.eyeColor = eyecolor; } Person.prototype.name = function() { return this.firstName + " " + this.lastName; };

Попробуйте сами »
Другие расширения