В JavaScript прототип и цепочка прототипов неизбежно являются важными понятиями, так как же понимать прототип и цепочку прототипов? Ниже приводится мое понимание и краткое изложение прототипов и цепочек прототипов. Возможно, некоторые понимания все еще поверхностны, и по прошествии времени и углублении понимания они будут добавлены в будущем. Если вы нашли что-то не так в моем понимании, пожалуйста, поправьте меня в комментариях.
1. Почему JavaScript разработан как шаблон, основанный на прототипах
В прошлом процессе обучения мы узнали, что он имеет три основные характеристики, изучая объектно-ориентированный язык java: инкапсуляция, наследование и полиморфизм. Что касается наследования, java и javascript не совсем одно и то же.
Итак, как именно устроен javascript? В первые дни браузер мог только просматривать содержимое веб-страницы, но не мог взаимодействовать с пользователем, то есть, когда мы вводили учетную запись и пароль для входа в систему, браузер не мог оценивать вводимый контент и нужно судить о контенте через сервер.Чтобы решить проблему, Netscape эту проблему придумывает вспомогательный скриптовый язык, работающий с java и чем-то похожий по синтаксису. Из этого видно, что на javascript влияет java, который является всеми типами объектов.Если есть объекты, будет задействован механизм наследования.Так каков же механизм наследования JS?
JS относится к дизайну java и использует оператор new для создания объектов, но отличается от java тем, что за new следует Construtor вместо Class .
// java 中生成一个对象
Person p = new Person() // Person 指的是类名
// js 生成一个对象
function Person (age) {
this.age = age
this.nation = 'China'
}
var father = new Person(42) // Person 指的是构造函数
var mingming = new Person(11)
2. Конструктор
Конструкторы также являются обычными функциями, и у них тоже есть свойство прототипа.Отличие от обычных функций в том, что они требуют, чтобы первая буква была заглавной. Если конструктор вызывается с оператором new, он должен выполнить четыре шага:
1. Создайте новый объект
2. Укажите это на новый объект
3. Выполните конструктор, чтобы добавить свойства и методы к новому объекту.
4. Верните этот новый объект
function Food (name) {
this.name = name
this.eat = function () {
console.log('eat')
}
}
var food = new Food('banana')
3. Прототип
Любая функция имеет свойство прототипа, которое указывает на объект-прототип. Таким образом, прототип на самом деле является объектом, свойства, определенные в прототипе, через наследование (осуществляемое оператором new), созданные объекты также имеют свойства.
Связь между прототипом и конструктором: в конструкторе есть свойство прототипа, через которое можно получить доступ к прототипу.
В качестве примера возьмем код в конструкторе. Food — это конструктор, Food.prototype — это прототип, а food — это объект, сгенерированный ссылкой на Food.prototype.
4. Экземпляр экземпляра
Экземпляр — это объект, созданный конструктором.При использовании оператора new объект-прототип конструктора присваивается свойству proto экземпляра.
Проще говоря, мы используем новый оператор для создания экземпляра еды, и мы можем использовать instanceof для проверки связи между экземпляром и конструктором.
function Food (name) {
this.name = name
this.eat = function () {
console.log('eat')
}
}
var food = new Food('banana') // 实例化
var res = food instanceof Food // 检查 food 是否为 Food 实例
console.log(res) // true
Когда мы определяем свойство в прототипе, это свойство будет присвоено экземпляру.
function Food (name) {
this.name = name
this.eat = function () {
console.log('eat')
}
}
var food = new Food('banana') // 实例化
var res = food instanceof Food // 检查 food 是否为 Food 实例
console.log(res) // true
// 原型定义属性
Food.prototype.type = 'object named Food'
var foodRes = food.type // 实例继承的属性
console.log(foodRes) // object named Food
5. Неявные прототипыproto
Любой объект будет иметьprotoСвойство, указывающее на объект-прототип, из которого получен конструктор текущего объекта. Поскольку это свойство не является свойством, указанным в стандарте, не изменяйте значение этого свойства случайно, чтобы не нарушить цепочку прототипов. То есть экземпляры могут бытьprotoдоступ к свойствам прототипа.
в объектеprotoСвойства доступны не во всех реализациях, но можно использовать метод isPrototypeOf(), чтобы определить, существует ли такая связь между объектами.
function Food (name) {
this.name = name
this.eat = function () {
console.log('eat')
}
}
var food = new Food('banana') // 实例化
console.log(food.__proto__ === Food.prototype) // true
console.log(Food.prototype.isPrototypeOf(food)) // true
6. Конструктор
Конструктор может получить доступ к прототипу через свойство Prototype, тогда прототип также доступен для конструктора каким-то образом, который является конструктором свойства в прототипе, который не является реальным конструктором, и истинный конструктор ссылается на конструктор, оба не путай.
function Food (name) {
this.name = name
this.eat = function () {
console.log('eat')
}
}
var food = new Food('banana')
console.log(Food.prototype.constructor === Food) //true
Ключ: конструктор прототипа указывает на сам конструктор
Тогда отношения между конструктором, прототипом и экземпляром должны быть такими:
Чтобы лучше понять этот процесс, я разберу его для вас через историю:
1.Давным-давно скульптору попалась очень тонкая ваза (прототип Еда.прототип)
2. Однажды он захотел разбогатеть на массовом производстве и повторной гравировке этой вазы, поэтому он сначала проанализировал вазу, восстановил процесс резьбы и спроектировал производственную линию (конструктор Еда).
3. Затем на этой производственной линии вырезается множество реплик ваз. (пример еды)
7. Цепочка прототипов
proto — это атрибут, который есть у любого объекта.В js будет сформирована цепочка protos, и к proto будет осуществляться рекурсивный доступ до тех пор, пока значение не станет нулевым.Цепочка отношений, формируемая этим процессом поиска, является цепочкой прототипов.
function Food (name) {
this.name = name
this.eat = function () {
console.log('eat')
}
}
var food = new Food('banana') // 实例化
// 原型链
console.log(food.__proto__) // Food {}
console.log(food.__proto__.__proto__) // {}
console.log(food.__proto__.__proto__.__proto__) // null
Как показано ниже:
Суммировать
1. Каждая созданная функция будет иметь свойство прототипа, которое является указателем на объект, являющийся объектом-прототипом (Food.prototype).
2. Конструктор свойств по умолчанию для объекта-прототипа также является указателем на связанный с ним конструктор.
3. Объект-экземпляр, сгенерированный оператором new, будет иметь внутреннее свойство, указывающее на объект-прототип, и объект-экземпляр может получить доступ ко всем свойствам и методам объекта-прототипа.
4. Экземпляры могут обращаться к объектам-прототипам через внутренние указатели, а объекты-прототипы также могут находить конструкторы через конструктор.
5. Каждый конструктор имеет объект-прототип, объект-прототип содержит указатель на конструктор, а экземпляр содержит внутренний указатель на объект-прототип.
6.protoУказатель на _ зависит от того, как объект был реализован при его создании.
7. Экземпляр конструктора, инкапсулированная функция, является конструктором, если он вызывается с помощью оператора new, в противном случае он им не является.
8. Поиск атрибута во всей цепочке прототипов влияет на производительность: чем выше объект-прототип, тем больше влияние на производительность.
9. Все в JS - это объект. Объект функции, который проходит через новую функцию, является функцией, конструктор которой является функцией, и конструктор обычных объектов является объектом.
10. Каждый объект имеетprotoсвойство, и каждый объект функции имеет свойство прототипа.
Справочный источник
Продвинутое программирование на JavaScript
наконец
Если вы внимательно прочитали эту статью, я полагаю, что у вас появится новое понимание JavaScript в прототипе и цепочке прототипов. Если вы чувствуете, что вам помогут, помнитеподобноОй! Если вы найдете что-то не так с моим пониманием, вы можете исправить это в комментариях.