Легко понять цепочку прототипов JS

JavaScript
Легко понять цепочку прототипов JS

Понимание концепции прототипа и цепочки прототипов в js, безусловно, является необходимым шагом, чтобы помочь нам глубже изучить js.Например, если разработчики js хотят понять наследование js, принцип нового ключевого слова, даже инкапсулировать компоненты, оптимизировать код и понять прототип в js, цепочка прототипов является обязательным условием. В этой статье я использую самые краткие слова, чтобы ясно объяснить отношение равенства цепочки прототипов и смысл существования прототипа и цепочки прототипов.Прочитав эту статью, вы обнаружите, что прототип и цепочка прототипов так просто!

WechatIMG114.jpegПриведенную выше классическую диаграмму равенства цепочек прототипов, согласно следующему исследованию, вы легко освоите.

1: Понимание отношения равенства между прототипом и цепочкой прототипов

首先我们要清楚明白两个概念:

  1. js делится нафункциональная параСлон инормальный объект, у каждого объекта есть свойство __proto__, но только у функциональных объектов есть свойство прототипа
  2. Объект и функция встроены в js.функция, аналогично нашему обычно используемому Array, RegExp, Date, Boolean, Number, String

Пожалуйста, прочтите вместе со мной эти два понятия трижды и запомните их, которые будут использоваться позже.

那么__proto__和prototype到底是什么,两个概念理解它们

  1. Свойство __proto__ — это объект, который имеет два свойства: конструктор и __proto__;
  2. Прототип объекта-прототипа имеет свойство конструктора по умолчанию, которое используется для записи того, каким конструктором был создан экземпляр;

Пожалуйста, прочтите вместе со мной эти два понятия трижды и запомните их, которые будут использоваться позже.

Существует следующий конструктор Person, и его прототип имеет атрибут motherland='China'

 function Person(name, age){ 
    this.name = name;
    this.age = age;
 }
 
 Person.prototype.motherland = 'China'

Экземпляр Person01, созданный новым Person()

 let person01 = new Person('小明', 18);

js之父在设计js原型、原型链的时候遵从以下两个准则

1. Person.prototype.constructor == Person // **准则1:原型对象(即Person.prototype)的constructor指向构造函数本身**
2. person01.__proto__ == Person.prototype // **准则2:实例(即person01)的__proto__和原型对象指向同一个地方**

Пожалуйста, прочитайте эти два правила вместе со мной три раза и запомните их, которые будут использоваться позже.

помните вышеЧетыре концепции и два принципа, любое суждение о равенстве цепочки прототипов может быть оценено правильно;

Вы можете сравнить изображение выше, чтобы убедиться, что критерии вашей концепции ясны. Обязательно сравните изображение выше.

// 从上方 function Foo() 开始分析这一张经典之图
function Foo()
let f1 = new Foo();
let f2 = new Foo();

f1.__proto__ = Foo.prototype; // 准则2
f2.__proto__ = Foo.prototype; // 准则2
Foo.prototype.__proto__ = Object.prototype; // 准则2 (Foo.prototype本质也是普通对象,可适用准则2)
Object.prototype.__proto__ = null; // 原型链到此停止
Foo.prototype.constructor = Foo; // 准则1
Foo.__proto__ = Function.prototype; // 准则2
Function.prototype.__proto__  = Object.prototype; //  准则2 (Function.prototype本质也是普通对象,可适用准则2)
Object.prototype.__proto__ = null; // 原型链到此停止
// **此处注意Foo 和 Function的区别, Foo是 Function的实例**

// 从中间 function Object()开始分析这一张经典之图
function Object()
let o1 = new  Object();
let o2 = new  Object();

o1.__proto__ = Object.prototype; // 准则2
o2.__proto__ = Object.prototype; // 准则2
Object.prototype.__proto__ = null; // 原型链到此停止
Object.prototype.constructor = Object; // 准则1
// 所有函数的__proto__  都和 Function.prototype指向同一个地方
Object.__proto__ = Function.prototype // 准则2 (Object本质也是函数);
// 此处有点绕
Function.prototype.__proto__ =  Object.prototype; // 准则2 (Function.prototype本质也是普通对象,可适用准则2)
Object.prototype.__proto__ = null; // 原型链到此停止

// 从下方 function Function()开始分析这一张经典之图
function Function()
Function.__proto__ = Function.prototype // 准则2
Function.prototype.constructor = Function; // 准则1

Отсюда можно сделать вывод, что: В дополнение к объекту-прототипу Object.Prototype__proto__ указывает на Null, объекты-прототипы другого объекта встроенной функции (например: array.prototype) и пользовательский конструктор __proto__ all указывает на Object.Prototype, потому что сам объект-прототип является обычным объектом. который:

Object.prototype.__proto__ = null;
Array.prototype.__proto__ = Object.prototype;
Foo.prototype.__proto__  = Object.prototype;

Второе: в чем смысл прототипа и цепочки прототипов

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

Используя конструктор Person и экземпляр person01 в начале нашей статьи в качестве примера:

console.log(person01)

Печать person01, у него есть собственное имя атрибута = «Сяо Мин», возраст = 18. В то же время через цепочку отношений прототипа у него есть атрибут родина = «Китай»;

Давайте снова создадим экземпляр person2

let person02 = new Person('小花', 20);
console.log(person02)

打印person02, 他有自己属性 name = '小花',age = 20; 同时通过原型链关系,他有属性motherland = 'China'; 看出来了没有,原型对象存放了person01、person02共有的属性所属国motherland = 'China'. 我们不用在每个实例上添加motherland 属性,而是将这一属性存在他们的构造函数原型对象上,对于人类Person这样的构造函数。相同的属性、方法还有很多很多,比如我们是黑头发,我们都有吃,睡这样一个方法,当相同的属性、方法越多,原型、原型链的意义越大。 Тогда мы можем сделать это

Person.prototype.hairColor = 'black';
Person.prototype.eat = function(){
    console.log('We usually eat three meals a day.')
}
console.log(person01)
console.log(person02)

На этом этапе мы снова печатаем person01 и person02.Мы были приятно удивлены, обнаружив, что у них есть атрибуты hairColor и метод eat, экземпляры динамически получают атрибуты и методы, добавленные после конструктора Person, в чем смысл прототипа и цепочки прототипов. ! Его можно получить динамически, что может сэкономить память.

Еще одно замечание: если person01 покрасит волосы в желтый цвет, каким будет цвет волос?

person01,hairColor = 'yellow';
console.log(person01)
console.log(person02)

Видно, что цвет волос человека 01 = "желтый", а цвет волос человека 02 = "черный"; Объект экземпляра перезаписывает зодиак и методы, унаследованные от прототипа, что эквивалентно "покрытию свойств и экранированию свойств". Эта операция не изменит свойства и методы прототипа и, естественно, не изменит другие экземпляры, созданные унифицированным конструктор Только путем изменения свойств и методов объекта-прототипа можно изменить свойства и методы, полученные другими экземплярами через цепочку прототипов.

Три: Заключение

Если вам понравилась эта статья, пожалуйста, дайте мне небольшую поддержку.Если вы чувствуете, что написали неясно, пожалуйста, поправьте меня в комментариях! Раньше я всегда читал статьи и блоги других людей и многому научился у них.Это первый раз, когда я публикую техническую статью.Я надеюсь обменяться с вами технологиями и вместе добиться прогресса.