Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   __proto__ и prototype в JavaScript (https://javascript.ru/forum/misc/81655-__proto__-i-prototype-v-javascript.html)

voraa 07.01.2021 19:44

А откуда у нашей fun взялся метод apply?
Все оттуда же. Функция - объект
Любая функция создается с помощью (неявного) вызова new Function()
Мы написали
function fun() {...}

На самом деле получили
var fun = new Function(....)


Function - встроенная функция JS. Как и любая функция она содержит свойство prototype
Function.prototype = {
   constructor: Function,
// и прочие методы
   apply: function () {...},
   call: function () {...},
   bind: function () {...},
.....
}


Когда вызвался fun = new Function (...)
как и для всех объектов произошло
fun.__proto__ = Function.prototype;

Поэтому методы apply, call, bind... стали доступны для fun

voraa 07.01.2021 20:58

На самом деле все немного сложнее.
У объектов нет никакого свойства __proto__. Есть внутреннее, недоступное из программ свойство [[Prototype]]. А __proto__ это getter/setter из Object.prototype - системные функции JS, которые могут получать/менять [[Prototype]] объектов. Они доступны из объектов через цепочку прототипов. Если она не нарушена.
let op = {
	x: 1,
	y: 2
};

let o ={};
o.__proto__ = op;

console.log (o.__proto__); // {x:1, y:2} здесь идет обращение к Object.prototype get __proto__
console.log (o.x, o.y); // 1 2   это из прототипа

o.__proto__ = null;

console.log (o.x, o.y); // undefined undefined  т.к. нет прототипа

o.__proto__ = op;

console.log (o.__proto__) // по прежнему {x:1, y:2} но это не прототип! это обычное свойство __proto__
console.log (o.x, o.y); // и по прежнему undefined undefined т.к. нет прототипа. И никогда не будет.


Написав o.__proto__ = null, мы нарушили цепочку прототипов. Из нашего объекта теперь невозможно добраться до Object.prototype и нет доступа к setter __proto__. Поэтому, когда мы снова пишем o.__proto__ = op, то не меняем прототип [[Prototype]], а просто создаем обычное свойство с именем __proto__. Оно ссылается на op, но это не имеет никакого отношения к прототипу объекта

MallSerg 08.01.2021 01:58

>>
Цитата:

Сообщение от denis_alekss
Сообщение от MallSerg
>>
И изучи из чего состоит полученный объект.

ff = function fun (){};
f = new ff();

console.dir(f);
Этот объект состоит из:

1. функции fun
2. конструктора fun
3. __proto__ ссылается на функцию-класс с помощью которого он был создан, то есть на функцию fun.
4. Сама функция fun ссылается на Object.prototype

Я привет пример кода выполнив который в консоли браузера ты должен был получить в ответ объект.

Приведенный пример кода состоит из трех строк каждая из которых является выражением.
1. используется функциональное выражение (function fun (){})
для создания функционального объекта и присваивание(взятие ссылки) его переменной ff.
ff хранит ссылку на функциональный объект который можно вызвать как функцию используя эту ссылку ff.
2. Вызов по ссылке(ff) функции(fun) как конструктора для нового объекта типа (fun) и сохранение полученного нового объекта в переменную f
3. команда консоли вывести объект на который ссылается переменная f.

>> Конструктор как выглядит здесь?
Здесь в роли конструктора выступает функция fun (function fun (){}; )
Любой функциональный объект в JavaScript может быть использован как функция конструктора.
В JavaScript нет разницы между функциями и конструкторами.

>> Он создается для потомков?
Для создания потомков конструктор не нужен т.к. ему нечего и незачем конструировать.
Наследникам для получения наследства в виде свойств и методов достаточно просто стать наследниками.
т.е. указать ссылкой на свой прототип.

ИМХО твоя проблема в том что абстракции и понятия используемые в компилируемых языках где требуются описания различных классов объектов и описанию по их построению(конструкторы/деструкторы) ты пытаешься использовать в JavaScript и приходишь к противоречиям и непоняткам ставящим тебя в тупик непонимания.
JavaScript это другой язык построенный на отличающихся абстракциях и понятиях.


Часовой пояс GMT +3, время: 20:57.