
В JavaScript функция — это объект типа Function , который содержит свойства и методы. Прототип (Prototype) — атрибут объекта типа Function .
Атрибут prototype включается при определении функции, а его начальное значение — пустой объект. В JavaScript для функций не определен тип прототипа, поэтому прототип может быть любого типа.
Прототип используется для сохранения общих свойств и методов объекта . Свойства и методы прототипа не влияют на свойства и методы самой функции.
// Свойства типа функции -> свойства, которые есть у всех функций console.log(Function.prototype); //[Function]
//Определение функции function fn() {
console.log('это функция');
}
//Значением прототипа по умолчанию является пустой объект console.log(fn.prototype); //fn {}
// Функция содержит конструктор --> все ссылочные типы на самом деле являются конструкторами console.log(Number.prototype); //[Number: 0]
console.log(Object.prototype);//{} Вы можете получить прототип объекта двумя способами установки общих свойств и методов:
prototype конструктораgetPrototype метода объекта Object (obj).функция фн() {
console.log('это функция');
}
//Используем структуру синтаксиса атрибутов объекта доступа console.log(fn.prototype); //fn {}
console.log(fn['prototype']);//fn {}
//Тип объекта предоставляет метод getPrototypeOf() console.log(Object.getPrototypeOf(fn)); //[Функция]Метод Object.getOwnPropertyDescriptors() используется для получения дескрипторов всех собственных свойств объекта.
var result = Object.getOwnPropertyDescriptor(Object.prototype,'constructor');
console.log(result) //Результаты вывода следующие:
//{
// значение: [Функция: Объект],
// доступно для записи: правда,
// перечисляемое: ложь,
// настраивается: правда
// }
constructor是在创建函数的时候自动添加的,指向构造函数本身
Вы можете установить свойства и методы прототипа следующими двумя способами:
Constructor.prototype.Attribute name = значение атрибута; Constructor.prototype.Method name = function(){}; Когда нам нужно добавить к прототипу много атрибутов, слишком сложно снова и снова писать
构造函数.prototype.属性名. Мы можем напрямую изменить весьprototype
.
Имя атрибута: значение атрибута,
Имя метода: function(){}} function foo() {}foo.prototype = {
конструктор: фу,
название: 'варенье',
возраст: 18,
адрес: 'Пекин'}var fn = new foo()console.log(fn.address) //Пекин Каждый объект будет иметь метод isPrototypeOf() , который используется для определения того, является ли объект прототип другого объекта.
Пример кода выглядит следующим образом:
// Определить объект через инициализатор var obj = {
название: 'джем'
}
//Определяем функцию-конструктор Hero() {}
// Назначаем объект obj прототипу конструктора Hero Hero.prototype = obj;
// Создать объект с помощью конструктора var Hero = new Hero();
// Метод isPrototypeOf() определяет, является ли указанный объект прототипом другого объекта var result = obj.isPrototypeOf(hero);
console.log(result);//true проверяет, что объект
objявляется прототипом объекта-hero
Далее мы используем фрагмент кода, чтобы расширить наше понимание цепочки прототипов:
Сценарий : Найти объекты на объекте obj. Шаги, выполняемые атрибутом адреса js:
1. Будет запущена операция получения. 2. Поиск атрибута в текущем объекте. 3. Если он не найден, в этот момент будет выполнен поиск в объекте цепочки прототипов (__proto__). 1. Поиск завершится. Если он не найден, он продолжит поиск по цепочке прототипов, пока не будет найден прототип верхнего уровня (что такое прототип верхнего уровня, временно неясно) var obj = {.
название: 'варенье',
возраст: 19
}
/*
Требование: Найдите атрибут адреса объекта obj*/.
// Цепочка прототипов ищется слой за слоем. Если она не найдена, поиск будет осуществляться до тех пор, пока не будет найден прототип верхнего уровня.
obj.__proto__.__proto__ = {}
obj.__proto__.__proto__.__proto__ = {
адрес: «Пекин»
}
console.log(obj.address) // Пекин console.log(obj.__proto__.__proto__.__proto__) // { адрес: 'Пекин' } 
Наконец найдите атрибут адреса
那么这里有一个问题,如果一直没有查到,会无穷尽的去查找吗?接下来我们就来了解一下
Как мы уже упоминали выше, мы не будем бесконечно искать по цепочке прототипов. Когда прототип верхнего уровня будет найден, будет возвращено undefined , если он еще не найден.
Так что же такое прототип верхнего уровня?
Пример кода выглядит следующим образом:
var obj = { name: 'jam' }console.log(obj.__proto__) // {}console.log(obj.__proto__.__proto__) // Прототип объекта obj с нулевым литералом:
{}.{}— это прототип верхнего уровня. Когда мы продолжаем печатать__proto__вверх, возвращается нулевое значение, что доказывает, что предыдущий слой уже является прототипом верхнего уровня.
Следующий рисунок является дополнением к прототипу верхнего уровня. отсутствует в первом фрагменте кода: 
顶层原型就是Object.prototype
3.1 Так где же находится конец цепочки прототипов? Например, есть ли у третьего объекта атрибут прототипа __proto__ ?
var obj = {name:'jam'}obj.__proto__ = {}obj.__proto__.__proto__ = {}obj.__proto__.__proto__.__proto__ = {}console.log(obj.__proto__.__proto__.__proto__.__proto__) // {} Мы обнаружили, что напечатанный выше результат представляет собой空对象{}
var obj = {
название: 'варенье',
возраст: 19
}
console.log(obj.__proto__) // {}
console.log(Object.prototype) // {}
console.log(obj.__proto__ === Object.prototype) // true Object является родительским классом для всех классов, поэтому obj.__proto__ на самом деле является Object.prototype,
console.log(obj.__proto__ === Object.prototype) // trueмы видим, что результат Object.prototype является прототипом верхнего уровня.
{}3.2 Тогда мы можем спросить. : {} Есть ли что-то особенное в прототипах?
console.log(obj.__proto__.__proto__.__proto__.__proto__.__proto__) // null;
Object.prototype является пустой объект {}, он не пуст, но свойства внутри не перечисляемы. Например, давайте напечатаем constructor свойство для просмотра <!-- Видно, что атрибут конструктора существует и он не пуст -->console.log(Object.prototype.constructor) // [Функция: Object] <!-- конструктор ссылается на Object -->
Object.prototype с помощью метода Object.getOwnPropertyDescriptors() . console.log(Object.getOwnPropertyDescriptors(Object.prototype)) //Как показано на длинном скриншоте ниже

