Наиболее сложным и трудным для понимания ПОЧЕМУ и КАК JavaScript является механизм прототипа.

Оставляя позади все положительные или отрицательные комментарии, абсолютно необходимо понять, как это в целом работает.

Вот некоторые моменты, которые сложно обнаружить:

Перед тем, как отправиться в путешествие, примите во внимание, что в этом письме

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

Давайте начнем.

Функция, Function.prototype, Object, Object.prototype встроены в JavaScript. Посмотрите на диаграмму, чтобы увидеть их свойства и отношения между ними.

Вот несколько важных наблюдений:

  • Функция - единственная функция, у которой свойство доступа __proto__ и свойство данных prototype указывают на один и тот же объект: Function.prototype
  • Таким образом, мы можем сказать, что Функция - единственная функция, которая сама себя рождает. (Можно сказать, что функция косвенно является конструктором самой себя)
  • Доказательство: Function.prototype.constructor относится к объекту Function.prototype.
console.log(Function.prototype.constructor == Function) // true
console.log(Function.__proto__ == Function.prototype) // true
console.log(Function.__proto__.constructor == Function) // true
  • Объект Function.prototype - это то, что делает все функции особенными (вызов и применение находятся в Function.prototype).
  • Все остальные функции в нашем коде создаются с помощью вызова конструктора функции (новая функция (.., ..))
  • Все остальные функции, созданные с помощью new Function (), возвращают
  1. Объект Function.prototype через свойство аксессора __proto__
  2. Недавно созданный объект functionName.prototype через средство доступа к данным прототипа.

Посмотрим на это

  • Когда компилятор встречает объявление функции (случай 1) или выражение функции (случай 2), он вызывает конструктор к функции. (новая функция (.., ..))
  • Этот вызов конструктора возвращает новый экземпляр объекта. (это то, что всегда делает оператор new)
  • Этот экземпляр объекта (который является функциональным объектом) (в дальнейшем назовем этот функциональный объект Y) навсегда прикреплен к своей лексической области. Следовательно, этот функциональный объект (Y) всегда сможет достичь своей родительской области. Однако родительская область еще не знает о существовании этого функционального объекта.
  • Если это было объявление функции (случай 1), новая переменная (которая равна имени функции) создается в родительской области и ссылке на вновь созданную функцию. объект (Y) присваивается переменной.
  • Если это было выражение функции (случай 2), это выражение возвращает ссылку на вновь созданный объект функции (Y). (следовательно, может храниться в переменной, передаваться как аргумент (обратный вызов) или возвращаться (функция высшего порядка))
  • Теперь, поскольку объект функции (Y) находится там, где существует инструкция или объявление, можно перемещать только ссылку на этот объект (Y). Таким образом, даже если вы думаете, что передаете значение функции в качестве аргумента или думаете, что возвращаете значение функции, на самом деле происходит создание объекта функции. прямо здесь, но передается или возвращается только ссылка на этот объект. Вот почему работает закрытие. Вы всегда вызываете функцию там, где она выражена или объявлена; следовательно, функция всегда ищет одну и ту же область видимости.
  • Еще одна вещь, которую выполняет вызов конструктора (new Function (.., ..)), - это то, что он присваивает Function.prototype вновь созданному объекту функции ( Y) внутренний [[prototype]] (через сеттер в Object.prototype.) В дальнейшем, если вы обращаетесь к __proto__ в этом вновь созданном объекте функции (Y ), он вернет Function.prototype
  • Последнее, что происходит: создается новый объект: Y.prototype
  • Y.prototype имеет единственное свойство: конструктор
  • Y.prototype.constructor ссылается на Y
  • Поскольку все функции в нашем коде созданы с помощью Function, свойство аксессора __proto__ всех этих функций указывает на Function.prototype
function Y(){}
console.log(Y.__proto__.constructor === Function); // true
console.log(Y.__proto__ == Function.prototype); // true
  • Теперь у нас есть переменная Y, которая указывает на функциональный объект, созданный с помощью Function.
  • Если мы вызываем Y оператором new (вызов конструктора)
  1. Создается новый объект (foo) (типа object).
  2. Для __proto__ установлено значение Y.prototype.
  3. foo .__ proto __. конструктор указывает на Y
var foo = new Y();
console.log(foo.__proto__ == Y.prototype) // true
console.log(foo.__proto__.constructor == Y) // true

Точно так же давайте посмотрим, что делает функция Object.

Когда мы вызываем конструктор Object (new Object ())

  1. Создан новый объект (полоса)
  2. Его свойство доступа __proto__ относится к Object.prototype.

Если вы относитесь к 18 миллионам жителей Стамбула, я преподаю JavaScript. Вы можете связаться со мной: +90 533 357 49 19

Я также провожу учебный курс по программированию: https://www.yenikodyazilimkursu.com

Проведите онлайн-экзамены для найма разработчиков программного обеспечения: https://www.testinvite.com/lang/en/online-exam-software.html