__proto__ VS. прототип в JavaScript
Этот рисунок снова показывает, что у каждого объекта есть прототип. Конструктор Функция Foo также имеет свой собственный __proto__
, который является Function.prototype, и который в свою очередь также ссылается через свое свойство __proto__
снова на Object.prototype. Таким образом, повторяю, Foo.prototype просто явный свойство Foo, которое ссылается на прототип объектов b и c.
var b = new Foo(20);
var c = new Foo(30);
В чем различия между __proto__
и prototype
?
Эта цифра взята с сайта dmitrysoshnikov.com.
Ответы
Ответ 1
__proto__
- это фактический объект, который используется в цепочке поиска для разрешения методов и т.д. prototype
- это объект, который используется для построения __proto__
при создании объекта с new
:
( new Foo ).__proto__ === Foo.prototype;
( new Foo ).prototype === undefined;
Ответ 2
prototype
является свойством объекта Function. Это прототип объектов, построенных этой функцией.
__proto__
- внутреннее свойство объекта, указывающее на его прототип. Существующие стандарты обеспечивают эквивалентный метод Object.getPrototypeOf(O)
, хотя фактический стандарт __proto__
выполняется быстрее.
Вы можете найти отношения instanceof
, сравнив функцию prototype
с цепочкой объектов __proto__
, и вы можете разбить эти отношения, изменив prototype
.
function Point(x, y) {
this.x = x;
this.y = y;
}
var myPoint = new Point();
// the following are all true
myPoint.__proto__ == Point.prototype
myPoint.__proto__.__proto__ == Object.prototype
myPoint instanceof Point;
myPoint instanceof Object;
Здесь Point
- это функция-конструктор, она строит объект (структуру данных) процедурно. myPoint
- объект, построенный с помощью Point()
, поэтому Point.prototype
в это время сохраняется в myPoint.__proto__
.
Ответ 3
Свойство прототипа создается при объявлении функции.
Например:
function Person(dob){
this.dob = dob
};
Свойство Person.prototype создается внутри, как только вы объявляете вышеуказанную функцию. Многие свойства могут быть добавлены в Person.prototype, которые совместно используются экземплярами Person, созданными с использованием new Person().
// adds a new method age to the Person.prototype Object.
Person.prototype.age = function(){return date-dob};
Стоит отметить, что Person.prototype
является литералом Object
по умолчанию (его можно изменить при необходимости).
Каждый экземпляр, созданный с помощью new Person()
имеет свойство __proto__
которое указывает на Person.prototype
. Это цепочка, которая используется для поиска свойства определенного объекта.
var person1 = new Person(somedate);
var person2 = new Person(somedate);
создает 2 экземпляра Person
, эти 2 объекта могут вызывать age
метод Person.prototype
как person1.age
, person2.age
.
На приведенном выше рисунке из вашего вопроса вы можете видеть, что Foo
- это Function Object
и поэтому он имеет ссылку __proto__
на Function.prototype
который, в свою очередь, является экземпляром Object
и имеет ссылку __proto__
на Object.prototype
. Ссылка прото заканчивается здесь с __proto__
в Object.prototype
указывая на null
.
Любой объект может иметь доступ ко всем свойствам в своей цепочке прототипов, которые связаны __proto__
, тем самым формируя основу для наследования прототипов.
__proto__
не является стандартным способом доступа к цепочке прототипов, стандартным, но похожим подходом является использование Object.getPrototypeOf(obj)
.
Ниже код для оператора instanceof
дает лучшее понимание:
Оператор объекта instanceof
Class возвращает true
когда объект является экземпляром класса, более конкретно, если Class.prototype
найден в цепочке Class.prototype
этого объекта, тогда объект является экземпляром этого класса.
function instanceOf(Func){
var obj = this;
while(obj !== null){
if(Object.getPrototypeOf(obj) === Func.prototype)
return true;
obj = Object.getPrototypeOf(obj);
}
return false;
}
Вышеуказанный метод может быть вызван как: instanceOf.call(object, Class)
который возвращает true, если object является экземпляром Class.
Ответ 4
Хороший способ подумать об этом...
prototype
используется функциями constructor()
. Это действительно должно было быть названо как "prototypeToInstall"
, так как это то, что оно есть.
и __proto__
- это "установленный прототип" объекта (который был создан/установлен на объект из указанной функции constructor()
)
Ответ 5
Чтобы объяснить, давайте создадим функцию
function a (name) {
this.name = name;
}
Когда JavaScript выполняет этот код, он добавляет prototype
свойства, a
prototype
свойство является объектом с двумя свойствами к нему:
-
constructor
-
__proto__
Итак, когда мы делаем
a.prototype
возвращает
constructor: a // function definition
__proto__: Object
Теперь, как вы можете видеть, constructor
- это не что иное, как сама функция a
, и __proto__
указывает на Object
JavaScript уровня корня.
Давайте посмотрим, что происходит, когда мы используем a
функцию с new
ключевым словом.
var b = new a ('JavaScript');
Когда JavaScript выполняет этот код, он выполняет 4 вещи:
- Создает новый объект, пустой объект //{}
- Он создает
__proto__
на b
и указывает на a.prototype
поэтому b.__proto__ === a.prototype
- Он выполняет
a.prototype.constructor
(который является определением функции a
) с вновь созданным объектом (созданным на шаге 1) в качестве его контекста (this), поэтому свойство name
передается как "JavaScript" (который добавляется к this
) добавляется к вновь созданному объекту. - Он возвращает вновь созданный объект в (созданный на шаге # 1), так что var
b
назначается вновь созданному объекту.
Теперь, если мы добавим a.prototype.car = "BMW"
и сделаем b.car
, b.car
вывод "BMW".
это потому, что когда JavaScript выполнял этот код, он искал свойство car
на b
, он не находил, а затем JavaScript использовал b.__proto__
(который был создан, чтобы указывать на "a.prototype" на шаге # 2) и находил свойство car
поэтому возвращаем " БМВ".
Ответ 6
При создании функции объект свойства с именем prototype создается автоматически (вы сами его не создавали) и присоединяется к объекту функции (constructor
).
Примечание. Этот новый объект-прототип также указывает или имеет внутренне-частную ссылку на собственный объект JavaScript.
Пример:
function Foo () {
this.name = 'John Doe';
}
// Foo has an object property called prototype.
// prototype was created automatically when we declared the function Foo.
Foo.hasOwnProperty('prototype'); // true
// Now, we can assign properties and methods to it:
Foo.prototype.myName = function () {
return 'My name is ' + this.name;
}
Если вы создадите новый объект из Foo
с помощью ключевого слова new
, вы в основном создадите (среди прочего) новый объект, имеющий внутреннюю или личную ссылку на прототип функции Foo
мы обсуждали ранее:
var b = new Foo();
b.[[Prototype]] === Foo.prototype // true
Закрытая связь с этим функциональным объектом называется прототипом в двойных скобках или просто [[Prototype]]
. Многие браузеры предоставляют нам общедоступную __proto__
которая называется __proto__
! Чтобы быть более конкретным, __proto__
на самом деле является функцией получения, которая принадлежит нативному объекту JavaScript. Он возвращает внутренне-частную связь прототипа любой привязки this
(возвращает [[Prototype]]
of b
):
b.__proto__ === Foo.prototype // true
Стоит отметить, что начиная с ECMAScript5
, вы также можете использовать метод getPrototypeOf для получения внутренней частной связи:
Object.getPrototypeOf(b) === b.__proto__ // true
ПРИМЕЧАНИЕ: этот ответ не предназначен для того, чтобы охватить весь процесс создания новых объектов или новых конструкторов, но чтобы помочь лучше понять, что такое __proto__
, prototype
и [[Prototype]]
и как это работает.
Ответ 7
Чтобы сделать его немного понятным в дополнение к вышестоящим замечательным ответам:
function Person(name){
this.name = name
};
var eve = new Person("Eve");
eve.__proto__ == Person.prototype //true
eve.prototype //undefined
Экземпляры имеют __ прото __, классы имеют прототип .
Ответ 8
В JavaScript функция может использоваться как конструктор. Это означает, что мы можем создавать объекты из них, используя ключевое слово new. Каждая функция конструктора имеет встроенный объект, связанный с ними. Этот встроенный объект называется прототипом. Instances of a constructor function use __proto__ to access the prototype property of its constructor function.
Сначала мы создали конструктор: function Foo(){}
. Чтобы быть понятным, Foo это просто еще одна функция. Но мы можем создать объект из него с новым ключевым словом. Вот почему мы называем это функцией конструктора
Каждая функция имеет уникальное свойство, которое называется свойством прототипа. Итак, функция Constructor Foo
имеет свойство prototype, которое указывает на его прототип, то есть Foo.prototype
(см. изображение).
Конструктивные функции сами являются функцией, которая является экземпляром системного конструктора, называемого конструктором [[Function]]. Таким образом, мы можем сказать, что function Foo
создается конструктором [[Function]]. Итак, __proto__
нашего Foo function
будет указывать на прототип его конструктора, который является Function.prototype
.
Function.prototype
сам по себе является ничем иным, как объектом, созданным из другого системного конструктора под названием [[Object]]
. Итак, [[Object]]
является конструктором Function.prototype
. Таким образом, мы можем сказать, что Function.prototype
является экземпляром [[Object]]
. Таким образом, __proto__
из Function.prototype
указывает на Object.prototype
.
Object.prototype
- последний человек, стоящий в цепи прототипов. Я имею в виду, что это не было построено. Это уже есть в системе. Таким образом, его __proto__
указывает на null
.
Теперь мы подошли к случаям Foo
. Когда мы создаем экземпляр, используя new Foo()
, он создает новый объект, который является экземпляром Foo
. Это означает, что Foo
является конструктором этих экземпляров. Здесь мы создали два экземпляра (x и y). __proto__
из x и y, таким образом, указывает на Foo.prototype
.
Ответ 9
Мне довелось изучать прототип из You Not Know JS: this & Object Prototypes, который является замечательной книгой, чтобы понять дизайн и объяснить множество заблуждений (вот почему я пытаюсь избежать использования наследования и таких вещей, как instanceof
),
Но у меня тот же вопрос, что и здесь. Несколько ответов действительно полезны и поучительны. Я также хотел бы поделиться своим пониманием.
Что такое прототип?
У объектов в JavaScript есть внутреннее свойство, обозначенное в спецификации как [[Prototype]]
, которое является просто ссылкой на другой объект. Почти всем объектам присваивается null
значение non- для этого свойства во время их создания.
Как получить прототип объекта?
через __proto__
или Object.getPrototypeOf
var a = { name: "wendi" };
a.__proto__ === Object.prototype // true
Object.getPrototypeOf(a) === Object.prototype // true
function Foo() {};
var b = new Foo();
b.__proto__ === Foo.prototype
b.__proto__.__proto__ === Object.prototype
Какой prototype
?
prototype
- это объект, автоматически создаваемый как специальное свойство функции, которое используется для создания цепочки делегирования (наследования), то есть цепочки прототипов.
Когда мы создаем функцию a
, prototype
автоматически создается как специальное свойство для a
и сохраняет код функции в качестве constructor
prototype
.
function Foo() {};
Foo.prototype // Object {constructor: function}
Foo.prototype.constructor === Foo // true
Я хотел бы рассмотреть это свойство как место для хранения свойств (включая методы) объекта функции. Это также причина, по которой служебные функции в JS определяются как Array.prototype.forEach()
, Function.prototype.bind()
, Object.prototype.toString().
Зачем подчеркивать свойство функции?
{}.prototype // undefined;
(function(){}).prototype // Object {constructor: function}
// The example above shows object does not have the prototype property.
// But we have Object.prototype, which implies an interesting fact that
typeof Object === "function"
var obj = new Object();
Итак, Arary
, Function
, Object
- все это функции. Я должен признать, что это освежает мое впечатление о JS. Я знаю, что функции - это первоклассный гражданин в JS, но кажется, что он построен на функциях.
В чем разница между __proto__
и prototype
?
__proto__
ссылка работает на каждый объект для ссылки на его свойство [[Prototype]]
.
prototype
- это объект, автоматически создаваемый как специальное свойство функции, которое используется для хранения свойств (включая методы) объекта функции.
С этими двумя мы могли мысленно наметить цепочку прототипов. Как эта картина иллюстрирует:
function Foo() {}
var b = new Foo();
b.__proto__ === Foo.prototype // true
Foo.__proto__ === Function.prototype // true
Function.prototype.__proto__ === Object.prototype // true
Ответ 10
Резюме:
Свойство __proto__
объекта - это свойство, которое отображается на prototype
функции конструктора объекта. Другими словами:
instance.__proto__ === constructor.prototype//true
Это используется для формирования цепочки prototype
объекта. Цепочка prototype
- это механизм поиска свойств объекта. При обращении к свойству объекта JavaScript сначала будет смотреть на сам объект. Если свойство там не найдено, оно будет подниматься до protochain
пока не будет найдено (или нет)
Пример:
function Person (name, city) {
this.name = name;
}
Person.prototype.age = 25;
const willem = new Person('Willem');
console.log(willem.__proto__ === Person.prototype); // the __proto__ property on the instance refers to the prototype of the constructor
console.log(willem.age); // 25 doesn't find it at willem object but is present at prototype
console.log(willem.__proto__.age); // now we are directly accessing the prototype of the Person function
Ответ 11
Еще один хороший способ понять это:
var foo = {}
/*
foo.constructor is Object, so foo.constructor.prototype is actually
Object.prototype; Object.prototype in return is what foo.__proto__ links to.
*/
console.log(foo.constructor.prototype === foo.__proto__);
// this proves what the above comment proclaims: Both statements evaluate to true.
console.log(foo.__proto__ === Object.prototype);
console.log(foo.constructor.prototype === Object.prototype);
Только после поддержки IE11 __proto__
. Перед этой версией, например IE9, вы можете использовать constructor
для получения __proto__
.
Ответ 12
Прототип
Прототип является свойством функции. Это проект создания объектов с использованием этой функции (конструктора) с новым ключевым словом.
__ прото __
__proto__
используется в цепочке поиска для разрешения методов, свойств. когда объект создается (с использованием функции конструктора с новым ключевым словом), __proto__
установлен в (конструктор) Function.prototype
function Robot(name) {
this.name = name;
}
var robot = new Robot();
// the following are true
robot.__proto__ == Robot.prototype
robot.__proto__.__proto__ == Object.prototype
Вот мое (воображаемое) объяснение, чтобы устранить путаницу:
Предположим, что существует воображаемый класс (чертеж/кокетка), связанный с функцией. Этот воображаемый класс используется для создания объектов. prototype
- это механизм расширения (метод расширения в С# или Swift Extension), чтобы добавить вещи к этому воображаемому классу.
function Robot(name) {
this.name = name;
}
Вышеизложенное можно представить как:
// imaginary class
class Robot extends Object{
static prototype = Robot.class
// Robot.prototype is the way to add things to Robot class
// since Robot extends Object, therefore Robot.prototype.__proto__ == Object.prototype
var __proto__;
var name = "";
// constructor
function Robot(name) {
this.__proto__ = prototype;
prototype = undefined;
this.name = name;
}
}
Итак,
var robot = new Robot();
robot.__proto__ == Robot.prototype
robot.prototype == undefined
robot.__proto__.__proto__ == Object.prototype
Теперь добавим метод к prototype
робота:
Robot.prototype.move(x, y) = function(x, y){ Robot.position.x = x; Robot.position.y = y};
// Robot.prototype.move(x, y) ===(imagining)===> Robot.class.move(x, y)
Вышеизложенное можно представить как расширение класса Robot:
// Swift way of extention
extension Robot{
function move(x, y){
Robot.position.x = x; Robot.position.y = y
}
}
Что, в свою очередь,
// imaginary class
class Robot{
static prototype = Robot.class // Robot.prototype way to extend Robot class
var __proto__;
var name = "";
// constructor
function Robot(name) {
this.__proto__ = prototype;
prototype = undefined;
this.name = name;
}
// added by prototype (as like C# extension method)
function move(x, y){
Robot.position.x = x; Robot.position.y = y
};
}
Ответ 13
Проще говоря:
> var a = 1
undefined
> a.__proto__
[Number: 0]
> Number.prototype
[Number: 0]
> Number.prototype === a.__proto__
true
Это позволяет прикрепить свойства к X.prototype ПОСЛЕ того, как объекты типа X были созданы, и они все равно получат доступ к этим новым свойствам с помощью ссылки __proto__, которую движок Javascript использует для приближения к цепочке прототипов.
Ответ 14
'use strict'
function A() {}
var a = new A();
class B extends A {}
var b = new B();
console.log('====='); // =====
console.log(B.__proto__ === A); // true
console.log(B.prototype.__proto__ === A.prototype); // true
console.log(b.__proto__ === B.prototype); // true
console.log(a.__proto__ === A.prototype); // true
console.log(A.__proto__ === Function.__proto__); // true
console.log(Object.__proto__ === Function.__proto__); // true
console.log(Object.prototype === Function.__proto__.__proto__); // true
console.log(Object.prototype.__proto__ === null); // true
В JavaScript каждый объект (функция также является объектом!) Имеет свойство __proto__
, свойство является ссылкой на его прототип.
Когда мы используем оператор new
с конструктором для создания нового объекта, свойство __proto__
нового объекта будет установлено со свойством prototype
конструктора, затем конструктор будет вызывать новый объект, в этом процессе "this" будет ссылкой на новый объект в области конструктора, наконец, вернуть новый объект.
Прототип конструктора - __proto__
свойство __proto__
свойство prototype
конструктора - работа с оператором new
.
Конструктор должен быть функцией, но функция не всегда является конструктором, даже если она имеет свойство prototype
.
Цепочка прототипов фактически является свойством объекта __proto__
для ссылки на его прототип, а свойство прототипа __proto__
для ссылки на прототип прототипа и т.д. До тех пор, пока не будет ссылки на свойство __proto__
прототипа объекта, которое ссылается на __proto__
.
Например:
console.log(a.constructor === A); // true
// "a" don't have constructor,
// so it reference to A.prototype by its ''__proto__'' property,
// and found constructor is reference to A
Свойство [[Prototype]]
и __proto__
фактически одно и то же.
Мы можем использовать метод Object getPrototypeOf, чтобы получить что-то прототип.
console.log(Object.getPrototypeOf(a) === a.__proto__); // true
Любая написанная нами функция может использоваться для создания объекта с оператором new
, поэтому любая из этих функций может быть конструктором.
Ответ 15
Prototype или Object.prototype - это свойство литерала объекта. Он представляет объект-прототип объекта, который вы можете переопределить, чтобы добавить дополнительные свойства или методы дальше по цепочке прототипов.
__ proto __ - это свойство accessor (функция get и set), которая предоставляет внутренний прототип объекта, к которому он обращается.
Литература:
Ответ 16
Я знаю, я опаздываю, но позвольте мне попытаться упростить его.
Скажем, существует функция
function Foo(message){
this.message = message ;
};
console.log(Foo.prototype);
Функция Foo будет иметь связанный прототип объекта. Итак, всякий раз, когда мы создаем функцию в JavaScript, у нее всегда есть связанный с ней объект-прототип.
Теперь давайте продолжим и создадим два объекта, используя функцию Foo.
var a = new Foo("a");
var b = new Foo("b");
console.log(a.message);
console.log(b.message);
- Теперь у нас есть два объекта: объект a и объект b. Оба созданы
используя конструктор Foo. Имейте в виду, что конструктор - это просто слово.
- Объект a и b имеют копию свойства сообщения.
- Эти два объекта a и b связаны с прототипом объекта конструктора Foo.
- На объектах a и b мы можем получить доступ к прототипу Foo, используя свойство proto во всех браузерах, а в IE мы можем использовать Object.getPrototypeOf(a) или Object.getPrototypeOf(b)
Теперь Foo.prototype, a. proto и b. proto все обозначает один и тот же объект.
b.__proto__ === Object.getPrototypeOf(a);
a.__proto__ === Foo.prototype;
a.constructor.prototype === a.__proto__;
все выше сказанное вернет true.
Как известно, свойства JavaScript могут добавляться динамически. Мы можем добавить свойство к объекту
Foo.prototype.Greet = function(){
console.log(this.message);
}
a.Greet();//a
b.Greet();//b
a.constructor.prototype.Greet();//undefined
Как вы видите, мы добавили метод Greet() в Foo.prototype, но он доступен в и b или любом другом объекте, который создается с помощью Foo.
При выполнении a.Greet() JavaScript сначала будет искать Greet в объекте в списке свойств. Не найдя, он будет расти в цепочке прото. Поскольку a. proto и Foo.prototype - это один и тот же объект, JavaScript найдет метод Greet() и выполнит его.
Надеюсь, теперь прототип и proto немного упрощены.
Ответ 17
ОПРЕДЕЛЕНИЯ
(число внутри скобки() - это "ссылка" на код, который написан ниже)
prototype
- объект, который состоит из:
= > функции (3) этого в частности, ConstructorFunction.prototype
(5), которые доступны каждому объект (4), созданный или созданный через эту конструкторскую функцию (1)
= > сама конструкторская функция (1)
= > __proto__
этого конкретного объекта (объект-прототип)
__proto__
(dandor proto?) - ссылка МЕЖДУ любым объектом (2), созданным через определенную конструкторскую функцию (1), И свойства объекта прототипа (5) этого конструктора THAT позволяют каждый созданный объект (2) имеет доступ к функциям и методам прототипа (4) (__proto__
по умолчанию включен в каждый отдельный объект в JS)
ПОДТВЕРЖДЕНИЕ КОДА
1.
function Person (name, age) {
this.name = name;
this.age = age;
}
2.
var John = new Person(‘John’, 37);
// John is an object
3.
Person.prototype.getOlder = function() {
this.age++;
}
// getOlder is a key that has a value of the function
4.
John.getOlder();
5.
Person.prototype;
Ответ 18
Пояснительный пример:
function Dog(){}
Dog.prototype.bark = "woof"
let myPuppie = new Dog()
теперь myPupppie имеет свойство __proto__
которое указывает на Dog.prototype.
> myPuppie.__proto__
>> {bark: "woof", constructor: ƒ}
но myPuppie НЕ имеет свойства прототипа.
> myPuppie.prototype
>> undefined
Итак, __proto__
в mypuppie - это ссылка на свойство .prototype функции конструктора, которое использовалось для создания экземпляра этого объекта (а текущий объект myPuppie имеет отношение "делегаты" к этому объекту __proto__
), в то время как свойство .prototype в myPuppie просто отсутствует (так как мы не установили его).
Хорошее объяснение MPJ здесь: proto против prototype - создание объектов в JavaScript
Ответ 19
Я попробую объяснение 4-го класса:
Все очень просто. A prototype
- пример того, как что-то должно быть построено. Итак:
-
Я function
, и я создаю новые объекты, похожие на мои prototype
-
Я object
, и я был построен с использованием моего __proto__
в качестве примера
доказательство
function Foo() { }
var bar = new Foo()
// `bar` is constructed from how Foo knows to construct objects
bar.__proto__ === Foo.prototype // => true
// bar is an instance - it does not know how to create objects
bar.prototype // => undefined
Ответ 20
Каждая созданная вами функция имеет свойство, называемое prototype
, и начинает свою жизнь как пустой объект. Это свойство бесполезно, пока вы не используете эту функцию в качестве функции конструктора, то есть с ключевым словом "новое".
Это часто путают с свойством __proto__
объекта. Некоторые могут запутаться и за исключением того, что свойство prototype
объекта может получить их прото объекта. Но это не случай. prototype
используется для получения __proto__
объекта, созданного из конструктора функций.
В приведенном выше примере:
function Person(name){
this.name = name
};
var eve = new Person("Eve");
console.log(eve.__proto__ == Person.prototype) // true
// this is exactly what prototype does, made Person.prototype equal to eve.__proto__
Ответ 21
Как использовать __proto__
для статических методов?
function Foo(name){
this.name = name
Foo.__proto__.collection.push(this)
Foo.__proto__.count++
}
Foo.__proto__.count=0
Foo.__proto__.collection=[]
var bar = new Foo('bar')
var baz = new Foo('baz')
Foo.count;//2
Foo.collection // [{...}, {...}]
bar.count // undefined
Ответ 22
(function(){
let a = function(){console.log(this.b)};
a.prototype.b = 1;
a.__proto__.b = 2;
let q = new a();
console.log(a.b);
console.log(q.b)
})()
Ответ 23
Свойство proto - это простое свойство accessor объекта Object.prototype, состоящее из функции getter и setter. Доступ к ресурсу для proto, который в конечном итоге справится с Object.prototype, найдет это свойство, но доступ, который не касается Object.prototype, не найдет его. Если какое-либо другое свойство proto найдено до использования объекта Object.prototype, это свойство скроет тот, который найден в Object.prototype.
Функция get proto предоставляет значение внутреннего [[Prototype]] объекта. Для объектов, созданных с использованием литерала объекта, это значение Object.prototype. Для объектов, созданных с использованием литералов массива, это значение - Array.prototype. Для функций это значение - Function.prototype. Для объектов, созданных с использованием нового удовольствия, где fun - одна из встроенных функций конструктора, предоставляемых JavaScript (Array, Boolean, Date, Number, Object, String и т.д.), Включая новые конструкторы, добавленные по мере развития JavaScript), это значение равно всегда fun.prototype. Для объектов, созданных с использованием нового развлечения, где fun - это функция, определенная в script, это значение является значением fun.prototype. (То есть, если конструктор не возвращал другой объект явно, или fun.prototype был переназначен с момента создания экземпляра).
Набор proto позволяет мутировать [[Prototype]] объекта. Объект должен быть расширяемым в соответствии с Object.isExtensible(): если это не так, генерируется TypeError. Предоставляемое значение должно быть объектом или нулевым. Предоставление любого другого значения ничего не сделает.
Чтобы понять, как прототипы используются для наследования, см. статью руководства Наследование и цепочку прототипов.
Ответ 24
__proto__
является базой для создания prototype
и функции конструктора, например: function human(){}
имеет prototype
который совместно используется через __proto__
в новом экземпляре функции конструктора. Более подробно читайте здесь
Ответ 25
Как это правильно сказано
__proto__
- это фактический объект, который используется в цепочке поиска для методы разрешения и т.д. прототип - это объект, который используется для построения __proto__
при создании объекта с новым:
( new Foo ).__proto__ === Foo.prototype;
( new Foo ).prototype === undefined;
Далее мы можем отметить, что свойство __proto__
объекта, созданного с использованием конструктора функции, указывает на область памяти, на которую указывает свойство prototype этого соответствующего конструктора.
Если мы изменим место в памяти прототипа функции конструктора, __proto__
производного объекта все равно будет продолжать указывать на исходное адресное пространство. Поэтому, чтобы сделать общее свойство доступным по цепочке наследования, всегда добавляйте свойство к прототипу функции конструктора, а не повторно инициализируйте его (что изменит его адрес памяти).
Рассмотрим следующий пример:
function Human(){
this.speed = 25;
}
var himansh = new Human();
Human.prototype.showSpeed = function(){
return this.speed;
}
himansh.__proto__ === Human.prototype; //true
himansh.showSpeed(); //25
//now re-initialzing the Human.prototype aka changing its memory location
Human.prototype = {lhs: 2, rhs:3}
//himansh.__proto__ will still continue to point towards the same original memory location.
himansh.__proto__ === Human.prototype; //false
himansh.showSpeed(); //25
Ответ 26
Существует только один объект, который используется для создания прототипа. Этот объект, очевидно, имеет имя и значение: __proto__
является его именем, а prototype
является его значением. Это все.
чтобы было еще проще понять, посмотрите на диаграмму в верхней части этого поста (Диаграмма Дмитрия Сошникова), вы никогда не найдете в качестве значения __proto__
что-то еще, кроме prototype
.
Суть в следующем: __proto__
- это имя, которое ссылается на объект-прототип, а prototype
- это действительный объект-прототип.
Это как сказать:
var x = {name: 'john'};
x
- это имя объекта (указатель), а {name: 'john'}
- фактический объект (значение данных).
ПРИМЕЧАНИЕ: это просто очень упрощенный намек на то, как они связаны на высоком уровне.
Ответ 27
Мое понимание: __proto__ и прототип служат для прототипа. разница заключается в том, что функции с индексом underscore (например, __proto__) не предназначены для разработчиков, явно вызываемых явно. другими словами, они предназначены только для некоторых механизмов, таких как наследование и т.д., они являются "back-end". но функции, названные без подчеркивания, предназначены для вызывания явно, они являются "front-end".
Ответ 28
!!! ЭТО ЛУЧШЕЕ ОБЪЯСНЕНИЕ В МИРЕ!!!!!
var q = {}
var prototype = {prop: 11}
q.prop // undefined
q.__proto__ = prototype
q.prop // 11
в конструкторах функций javascript engine вызывает это q.__proto__ = prototype
автоматически, когда мы пишем new Class
, а в __proto__
prop set Class.prototype
function Class(){}
Class.prototype = {prop: 999} // set prototype as we need, before call new
var q = new Class() // q.__proto__ = Class.prototype
q.prop // 999
Наслаждайтесь%)