Почему объекты не имеют значения прототипа, которые относятся к Object.prototype [duplicate]

Я согласен, что правильный инструмент для синтаксического анализа XML и , особенно HTML , является синтаксическим анализатором, а не механизмом регулярных выражений. Однако, как указывали другие, иногда использование регулярного выражения выполняется быстрее, проще и выполняется, если вы знаете формат данных.

Microsoft фактически имеет раздел Рекомендации по регулярным выражениям в .NET Framework и, в частности, говорит о . Рассмотрим [вход] источника входного сигнала .

Регулярные выражения имеют ограничения, но вы считали следующее?

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

По этой причине я считаю, что вы можете анализировать XML с помощью регулярных выражений. Обратите внимание, однако, что он должен быть достоверным. XML ( браузеры очень прощают HTML и допускают плохой синтаксис XML внутри HTML ). Это возможно, так как «Определение балансировки группы» позволит механизму регулярных выражений действовать как КПК.

Цитата из статьи 1, процитированной выше:

.NET Regular Expression Двигатель

Как описано выше, правильно сбалансированные конструкции не могут быть описаны регулярным выражением. Тем не менее, механизм регулярного выражения .NET предоставляет несколько конструкций, которые позволяют распознавать сбалансированные конструкции.

  • (?) - выталкивает захваченный результат в стек захвата с помощью группы имен.
  • (?<-group>) - отображает верхний захват с группой имен с захвата stack.
  • (?(group)yes|no) - соответствует дате, если существует группа с группой имен, в противном случае не соответствует какой-либо детали.

Эти конструкции допускают регулярную .NET выражение для подражания ограниченному КПК, по существу позволяя простые версии операций стека: push, pop и empty. Простые операции в значительной степени эквивалентны приращению, уменьшению и сравнению с нулем соответственно. Это позволяет механизму регулярного выражения .NET распознавать подмножество контекстно-свободных языков, в частности тех, которые требуют простого счетчика. Это, в свою очередь, позволяет нетрадиционным регулярным выражениям .NET распознавать индивидуально правильно сбалансированные конструкции.

Рассмотрим следующее регулярное выражение:

(?=)
(?>
                     |
   <[^>]*/>                      |
   (?<(?!/)[^>]*[^/]>)  |
   (?<-opentag>]*[^/]>)     |
   [^<>]*
)*
(?(opentag)(?!))

Использовать флаги :

  • Singleline
  • IgnorePatternWhitespace (необязательно, если вы сбрасываете регулярное выражение и удаляете все пробелы)
  • IgnoreCase (необязательно)

Объяснение регулярного выражения (inline)

(?=) # match start with 
    # atomic group / don't backtrack (faster) | # match xml / html comment <[^>]*/> | # self closing tag (?<(?!/)[^>]*[^/]>) | # push opening xml tag (?<-opentag>]*[^/]>) | # pop closing xml tag [^<>]* # something between tags )* # match as many xml tags as possible (?(opentag)(?!)) # ensure no 'opentag' groups are on stack

Вы можете попробовать это на A Better .NET Regular Expression Tester .

Я использовал источник выборки:




  • stuff...
  • more stuff
  • still more
    • Another >ul<, oh my!
    • ...

Это нашло совпадение:

   
  • stuff...
  • more stuff
  • still more
    • Another >ul<, oh my!
    • ...

, хотя оно получилось так:

  • stuff...
  • more stuff
  • still more
    • Another >ul<, oh my!
    • ...

Наконец, Мне очень понравилась статья Джеффа Этвуда: Parsing Html Путь Ктулху . Забавно, он цитирует ответ на этот вопрос, который в настоящее время имеет более 4 кв голосов.

604
задан 0x90 5 February 2017 в 02:45
поделиться

23 ответа

__proto__ - это фактический объект, который используется в цепочке поиска для разрешения методов и т. д. prototype - это объект, который используется для сборки __proto__ при создании объекта с помощью new:

( new Foo ).__proto__ === Foo.prototype;
( new Foo ).prototype === undefined;
575
ответ дан Adelin 16 August 2018 в 02:55
поделиться
  • 1
    Ах! Таким образом, prototype недоступен для самих экземпляров (или других объектов), но только для функций конструктора. – rvighne 6 August 2014 в 01:43
  • 2
    @rvighne: prototype доступен только для функций, поскольку они получены из Function, Function и Object, но ни в чем другом нет. Однако __proto__ доступен повсюду. – Tarik 27 September 2014 в 20:05
  • 3
    Таким образом, __proto__ - это фактический объект, который сохраняется и используется в качестве прототипа, тогда как Myconstructure.prototype является просто планом для __proto__, который, фактически, сохраняет фактический объект и используется в качестве protoype. Следовательно, myobject.prototype не будет свойством фактического объекта, потому что его просто временная вещь, используемая функцией конструктора для определения того, как выглядит myobject.__proto__. – Alex_Nabu 29 July 2015 в 03:38
  • 4
    Справедливо ли говорить, что свойство __proto__ объекта является указателем на свойство prototype функции конструктора объекта? т. е. foo .__ proto__ === foo.constructor.prototype – Niko Bellic 19 August 2015 в 02:10
  • 5
    @Alex_Nabu Не совсем. newCar.__proto__ IS Car.prototype, а не экземпляр Car.prototype. Пока Car.protoype IS экземпляр object. Car.prototype не является тем, что дает newCar любые свойства или структуру, просто IS следующий object в цепочке прототипов newCar. Car.prototype не является временным object. Это значение object установлено как значение свойства __proto__ для любых новых object s, сделанных с использованием Car в качестве constructor. Если вы хотите что-то придумать в качестве чертежа object, подумайте о Car как о плане для нового автомобиля object s. – seangwright 10 February 2016 в 03:56

Прототип или Object.prototype - это свойство литерала объекта. Он представляет объект прототипа Object , который вы можете переопределить, чтобы добавить дополнительные свойства или методы дальше по цепочке прототипов.

__ proto__ является свойством accessor (функция get и set), которая предоставляет внутренний прототип объекта, к которому он обращается.

Ссылки:

  1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype
  2. http://www.w3schools.com/js/js_object_prototypes.asp
  3. https://developer.mozilla.org/en-US/docs/Web/JavaScript / Reference / Global_Objects / Object / proto
3
ответ дан akodevs 16 August 2018 в 02:55
поделиться
  • 1
    Object.prototype не является свойством объектного литерала, попытка распечатать {}.prototype возвращает undefined; однако к нему можно получить доступ через {}.__proto__, который возвращает Object.prototype. – doubleOrt 7 September 2017 в 21:52

Проще говоря:

> var a = 1
undefined
> a.__proto__
[Number: 0]
> Number.prototype
[Number: 0]
> Number.prototype === a.__proto__
true

Это позволяет вам прикрепить свойства к X.prototype ПОСЛЕ того, как объекты типа X были созданы, и они все равно получат доступ к этим новым свойствам через __proto__ ссылка, которую Javascript-движок использует, чтобы подойти к цепочке прототипов.

4
ответ дан Andreas Bergström 16 August 2018 в 02:55
поделиться

Свойство proto - это простое свойство accessor на Object.prototype, состоящее из функции getter и setter. Доступ к ресурсу для прото, который в конечном итоге справится с Object.prototype, найдет это свойство, но доступ, который не касается Object.prototype, не найдет его. Если какое-либо другое свойство proto найдено до использования Object.prototype, это свойство скроет тот, который найден на Object.prototype.

Функция proto getter предоставляет значение внутреннего [[Prototype]] объект. Для объектов, созданных с использованием литерала объекта, это значение Object.prototype. Для объектов, созданных с использованием литералов массива, это значение - Array.prototype. Для функций это значение - Function.prototype. Для объектов, созданных с использованием нового удовольствия, где fun - одна из встроенных функций конструктора, предоставляемых JavaScript (Array, Boolean, Date, Number, Object, String и т. Д.), Включая новые конструкторы, добавленные по мере развития JavaScript), это значение равно всегда fun.prototype. Для объектов, созданных с использованием нового развлечения, где fun - функция, определенная в скрипте, это значение является значением fun.prototype. (То есть, если конструктор не возвращал другой объект явно, или fun.prototype был переназначен с момента создания экземпляра).

Прото-сеттер позволяет [[Прототип]] объект, подлежащий мутации. Объект должен быть расширяемым в соответствии с Object.isExtensible (): если это не так, генерируется TypeError. Предоставляемое значение должно быть объектом или нулевым. Предоставление любого другого значения ничего не сделает.

Чтобы понять, как прототипы используются для наследования, см. Статью руководства Наследование и цепочку прототипов.

0
ответ дан B.W 16 August 2018 в 02:55
поделиться

Как насчет использования __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
0
ответ дан Barrard 16 August 2018 в 02:55
поделиться
  • 1
    Именно поэтому ответ на & quot; __proto__ VS. prototype в JavaScript & quot; ? – Andreas 31 March 2018 в 09:29

Мое понимание: __proto__ и прототип служат для прототипа. разница заключается в том, что функции с индексом underscore (например, __proto__) не предназначены для разработчиков, явно вызываемых явно. другими словами, они предназначены только для некоторых механизмов, таких как наследование и т. д., они являются «back-end». но функции, названные без подчеркивания, предназначены для вызывания явно, они являются «front-end».

-1
ответ дан Beicai 16 August 2018 в 02:55
поделиться
  • 1
    Есть больше __proto__ и prototype, чем просто соглашение об именах. Они могут или не могут указывать на один и тот же объект. См. Ответ @zyklus. – demisx 25 August 2014 в 07:31
  • 2
    @demisx, конечно, вы сказали, что это правильно, но мое мнение - это различие в названиях, которое демонстрирует контрастность функциональности. – Beicai 11 October 2014 в 03:08
  • 3
    Этого недостаточно, чтобы заявить «в соответствии с вашим пониманием», особенно когда другие хорошие ответы были предоставлены до ... – ProfNandaa 8 August 2015 в 10:29

Я знаю, я опаздываю, но позвольте мне попытаться упростить его.

Скажем, существует функция

    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);
  1. Теперь у нас есть два объекта: объект a и объект b. Оба они создаются с использованием конструктора Foo. Имейте в виду, что конструктор - это просто слово.
  2. Объект a и b имеют копию свойства сообщения.
  3. Эти два объекта a и b связаны с прототипом объекта конструктора Foo.
  4. На объектах 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, но он доступен в a и b или любом другом объекте, который построен с использованием Foo.

При выполнении функции a.Greet () JavaScript сначала будет искать Greet в объекте в списке свойств. Не найдя, он будет расти в прото-цепочке a. Поскольку a.proto и Foo.prototype - это один и тот же объект, JavaScript найдет метод Greet () и выполнит его.

Надеюсь, теперь прототип и прото упрощаются.

3
ответ дан debugmode 16 August 2018 в 02:55
поделиться

__proto__ является базой для построения prototype и функции-конструктора, например: function human(){} имеет prototype, который совместно используется через __proto__ в новом экземпляре функции-конструктора. Более подробное чтение здесь

1
ответ дан Dev911 16 August 2018 в 02:55
поделиться
  • 1
    @Derick Daniel: не знаю, почему вы проголосовали за это, но сделанное вами изменение не было тем, что я пытался передать. Отредактировал его для большего зазора :). – Jyoti Duhan 13 July 2018 в 12:18
  • 2
    Jyoti, я не голосовал за ваш ответ, кто-то другой, я только что отредактировал его :) – Dev911 13 July 2018 в 14:16
  • 3
    @Derick Daniel: ok – Jyoti Duhan 14 July 2018 в 02:24

Еще один хороший способ понять это:

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__.

6
ответ дан doubleOrt 16 August 2018 в 02:55
поделиться
  • 1
    Только то, что я написал бы это по-другому: foo .__ proto__ === foo.constructor.prototype – epeleg 8 November 2015 в 11:10

ОПРЕДЕЛЕНИЯ

(число внутри скобки () - это «ссылка» на код, который написан ниже)

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;
2
ответ дан Eduard 16 August 2018 в 02:55
поделиться
Прототип прототипа

является свойством функции. Это проект создания объектов с помощью этой (конструктор) функции с новым ключевым словом.

__ proto __

__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 - механизм расширения (метод расширения в C # или 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
    };
}
4
ответ дан Hassan Tareq 16 August 2018 в 02:55
поделиться
  • 1
    все еще думая о более согласованных именах для __proto__ и прототипа. возможно, прототип и наследование? – Dmitry 1 April 2018 в 22:56
  • 2
    Я бы сказал, prototype & amp; __proto__ следует избегать. Сейчас у нас класс, и мне нравится ООП. – Hassan Tareq 2 April 2018 в 01:16
  • 3
    проблема в том, что класс относительно новый, и он не поддерживается действительно удобными машинами, такими как microsoft JScript (хорошо иметь при работе на C и нужен быстрый и грязный скриптовый движок, который всегда есть) и nashorn javascript (который поставляется со всеми новые установки Java под jjs и является хорошим способом превратить Java в чистую динамическую среду, где вам не нужно постоянно перекомпилировать вещи). Дело в том, что если класс был сахаром, это не проблема, но это не так, он предлагает вещи, которые невозможны без них в более старых версиях js. Подобно расширению «Функция». – Dmitry 2 April 2018 в 01:20
  • 4
    В конце концов мы получим поддержку. Я сторонний разработчик, поэтому у меня нет проблем, я редко программирую js. – Hassan Tareq 2 April 2018 в 01:24
  • 5
    и наследование статических членов таким образом, что добавление новых / удаление статических членов из родителя замечено дочерним элементом (что я не могу придумать, как сделать JScript, который не предлагает Object.assign / __ proto __ / getPrototypeOf, поэтому вы должны возиться с корневым Object.prototype, чтобы имитировать его) – Dmitry 2 April 2018 в 01:24

Я, случается, изучаю прототип из You Do not Know JS: this & amp; Object Prototypes , который является замечательной книгой, чтобы понять дизайн под ним и прояснить так много заблуждений (поэтому я стараюсь избегать использования наследования и таких вещей, как instanceof).

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


Что такое прототип?

Объекты в JavaScript имеют внутреннее свойство, обозначенное в спецификации как [[Prototype]], которое является просто ссылкой на другой объект.

Как получить прототип объекта?

через __proto__ или

для этого свойства во время их создания.

f9]

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();

So , Arary, Function, Object - все функции. Я должен признать, что это улучшает мое впечатление на JS. Я знаю, что функции являются первоклассными гражданами в JS, но кажется, что он построен на функциях.

В чем разница между __proto__ и prototype?

__proto__ a ссылка ссылается на каждый объект, чтобы ссылаться на его свойство [[Prototype]].

prototype - это объект, автоматически созданный как специальное свойство функции, которое используется для хранения свойств (включая методы) функциональный объект.

С этими двумя мы могли мысленно отобразить цепочку прототипов. Как показано на этом рисунке:

[/g5]

function Foo() {}
var b = new Foo();

b.__proto__ === Foo.prototype // true
Foo.__proto__ === Function.prototype // true
Function.prototype.__proto__ === Object.prototype // true
5
ответ дан ifyouseewendy 16 August 2018 в 02:55
поделиться

Прототип VS. __proto__ VS. [[Prototype]]

При создании функции создается объект свойства, названный прототипом автоматически (вы его не создали) и прикрепляется к объекту функции (constructor). Примечание. Этот новый объект prototype также указывает на встроенный 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__ на самом деле является функцией геттера , которые принадлежат к собственному объекту JavaScript , Он возвращает внутренне-частную прототипную привязку любой привязки this (возвращает [[Prototype]] в b):

b.__proto__ === Foo.prototype // true

Стоит отметить, что начиная с ECMAScript5, вы также может использовать метод getPrototypeOf для получения внутренней частной связи:

Object.getPrototypeOf(b) === b.__proto__ // true

ПРИМЕЧАНИЕ: этот ответ не предназначен для покрытия всего процесса создания новых объектов или новых конструкторов , но чтобы лучше понять, что это __proto__, prototype и [[Prototype]] и как это работает.

38
ответ дан Lior Elrom 16 August 2018 в 02:55
поделиться
  • 1
    @Taurus, нажмите на заголовок, он приведет к спецификации спецификации ECMAScript. Ознакомьтесь с разделом 9 (Обычное и экзотическое поведение объектов), которое объясняет это более подробно. – Lior Elrom 8 September 2017 в 02:20

!!! ЭТО ЛУЧШЕЕ ОБЪЯСНЕНИЕ В МИРЕ !!!!!

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

Наслаждайтесь%)

-3
ответ дан Maxmaxmaximus 16 August 2018 в 02:55
поделиться

Свойство прототипа создается при объявлении функции.

Например:

 function Person(dob){
    this.dob = dob
 }; 

Свойство Person.prototype создается внутренне после объявления над функцией. Многие свойства могут быть добавлены в Person.prototype, которые совместно используются экземплярами Person, созданные с использованием нового Person ().

// adds a new method age to the Person.prototype Object.
Person.prototype.age = function(){return date-dob}; 

Стоит отметить, что Person.prototype является Object литералом по умолчанию ( он может быть изменен по мере необходимости).

Каждый экземпляр, созданный с использованием нового Person (), имеет свойство __proto__, которое указывает на Person.prototype. Это цепочка, которая используется для перемещения, чтобы найти свойство определенного объекта.

var person1 = new Person(somedate);
var person2 = new Person(somedate);

создает 2 экземпляра Person, эти 2 объекта могут вызывать возрастное свойство Person.prototype как person1.age, person2.age.

На приведенном выше рисунке вы можете видеть что Foo является объектом Function и поэтому имеет ссылку __proto__ на Function.prototype, который, в свою очередь, является экземпляром Object и имеет ссылку __proto__ для Object.prototype. Протольная ссылка заканчивается здесь с __proto__ в Object.prototype, указывающем на null.

Любой объект может иметь доступ ко всем свойствам в своей прото-цепочке, связанным с __proto__, тем самым формируя основу для прототипное наследование.

__proto__ не является стандартным способом доступа к цепочке прототипов, стандартным, но аналогичным подходом является использование Object.getPrototypeOf (obj).

Ниже код для instanceof дает лучшее понимание:

object instanceof Оператор класса возвращает true, когда объект является экземпляром класса, более конкретно, если 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, если объект является экземпляром класса.

92
ответ дан Oxi 16 August 2018 в 02:55
поделиться
  • 1
    Мне было интересно, почему объект prototype был создан внутри себя в первую очередь? Можно ли просто назначить статические методы самому объекту функции. например function f(a){this.a = a}; f.increment = function(){return ++this.a}? Почему этот метод не выбран из-за добавления методов к объекту prototype? Это будет работать, если f.__proto__ = g, где g - базовый класс. – abhisekp 1 July 2016 в 16:08
  • 2
    Возможно, объект prototype был выбран для совместного использования, поскольку только свойства конструктора исключительных функций могут быть сохранены в объекте конструктора функций. – abhisekp 1 July 2016 в 16:10
  • 3
    На самом деле, это было бы беспорядок, потому что instanceof приведет к ({}) instanceof Function === true, поскольку не будет никакого способа дифференцировать прототипы, если свойство prototype будет удалено. – abhisekp 1 July 2016 в 16:58
  • 4
    @abhisekp Что вы подразумеваете под этим: & quot; Это будет работать, если f .__ proto__ = g, где g - базовый класс. & quot; Я не знаю, имеет ли это значение какое-то значение, которое я не понимаю, но если вы должны были добавить свойства и методы таким образом, тогда, когда вы использовали ключевое слово new для создания экземпляра, свойства и методы не будут использоваться, t будет скопирован. – doubleOrt 7 September 2017 в 21:22

Хороший способ подумать об этом ...

prototype используется функциями constructor(). Это действительно должно было называться, "prototypeToInstall", так как это то, что есть.

и __proto__ - это то, что «установленный прототип» на объекте (который был создан / установлен на объекте из constructor())

56
ответ дан sarink 16 August 2018 в 02:55
поделиться
  • 1
    Я поддержал его, но, возможно, причина нижнего уровня была в том, что прототип утверждения используется с помощью функций-конструкторов () может звучать так, как если бы функции-конструкторы не имели, что не так, но кроме того, теперь это не наш фокус, можно заметить, что каждая функция потенциально является конструктором, если вызывается с новым ... – yoel halb 2 February 2015 в 02:05
  • 2
    Пожалуйста, измените & quot; constructor() функции & quot; к «конструкторным функциям», поскольку может возникнуть путаница с «функциями __proto__.constructor()». Я считаю это важным, поскольку конструктор __proto __. фактически не вызывается, когда используется ключевое слово new. – Alexander Gonchiy 8 August 2015 в 04:15
  • 3
    Утверждение, что прототип используется конструкторами () функциями " говорит только о части важного факта, но сказал ему таким образом, что, вероятно, побудит читателей думать, что это весь факт. Прототип внутренне создан для каждого объявления функции в Javascript, независимо от того, как эта функция будет вызываться в будущем - с или без ключевого слова new ; Прототип объявленной функции указывает на литерал объекта. – Yiling 2 May 2016 в 07:19

Чтобы сделать это немного понятным в дополнение к следующим большим ответам:

function Person(name){
    this.name = name
 }; 

var eve = new Person("Eve");

eve.__proto__ == Person.prototype //true

eve.prototype  //undefined

У экземпляров есть __proto__, классы имеют прототип.

23
ответ дан serkan 16 August 2018 в 02:55
поделиться

(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) 
    })()

Попробуйте этот код, чтобы понять

1
ответ дан Suraj Rao 16 August 2018 в 02:55
поделиться

Каждая созданная вами функция имеет свойство, называемое 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__

Надеюсь, это имеет смысл.

1
ответ дан trincot 16 August 2018 в 02:55
поделиться
  • 1
    prototype не используется для создания __proto__ объекта. __proto__, при доступе, просто предоставляет ссылку на объект prototype. – doubleOrt 8 September 2017 в 11:20

В JavaScript функция может использоваться как конструктор. Это означает, что мы можем создавать объекты из них, используя новое ключевое слово. Каждая функция конструктора поставляется со встроенным объектом, связанным с ними. Этот встроенный объект называется прототипом. Экземпляры функции-конструктора используют __proto__ для доступа к прототипу его конструкторской функции.

  1. Сначала мы создали конструктор: function Foo(){}
  2. Функция конструктора Foo имеет свойство прототипа, которое указывает на его прототип, который является Foo.prototype (см. изображение).
  3. Конструкторные функции сами по себе являются функцией, которая является экземпляром конструктора системы, называемого конструктором [[Function]]. Таким образом, мы можем сказать, что function Foo строится конструктором [[Function]]. Таким образом, __proto__ нашего Foo function укажет на прототип своего конструктора, который является Function.prototype.
  4. Function.prototype сам по себе является не чем иным, как объектом, который построен из другого системного конструктора, называемого [[Object]]. Таким образом, [[Object]] является конструктором Function.prototype. Итак, мы можем сказать, что Function.prototype является экземпляром [[Object]]. Таким образом, __proto__ из Function.prototype указывает на Object.prototype.
  5. Object.prototype - последний человек, стоящий в цепи прототипов. Я имею в виду, что он не был построен. Это уже есть в системе. Поэтому его __proto__ указывает на null.
  6. Теперь мы приходим к экземплярам Foo. Когда мы создаем экземпляр с помощью new Foo(), он создает новый объект, который является экземпляром Foo. Это означает, что Foo является конструктором этих экземпляров. Здесь мы создали два экземпляра (x и y). __proto__ x и y указывает на Foo.prototype.
38
ответ дан TylerH 16 August 2018 в 02:55
поделиться
  • 1
    1. constructor не возвращается a()! Он возвращает a. 2. __proto__ возвращает Object.prototype, а не корневой объект в Javascript. – doubleOrt 7 September 2017 в 21:36

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__.

281
ответ дан user982671 16 August 2018 в 02:55
поделиться
  • 1
    Дэвид Герман прекрасно описывает это в своей новой книге effectivejs.com – nimrod 27 April 2013 в 06:26
  • 2
    Также, если вы измените свойство __proto__ объекта, оно изменит объект, по которому выполняются проверки прототипов. Например, вы можете добавить объект методов как функцию __proto__ функции, чтобы иметь объект вызываемого экземпляра. – kzh 19 August 2014 в 12:50
  • 3
    myPoint .__ proto __. constructor.prototype == Point.prototype – Francisco 21 March 2016 в 13:42
  • 4
    @kzh lol, который дал мне смешной результат console.log(obj1.call) // [Function: call] obj1.call() // TypeError: obj1.call не является функцией. Я сделал obj.__proto__ = Function.__proto__ – abhisekp 1 July 2016 в 16:37
  • 5
    myFn.__proto__ = {foo: 'bar'} – kzh 1 July 2016 в 19:41

Я попробую объяснение 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
1
ответ дан vladCovaliov 16 August 2018 в 02:55
поделиться
  • 1
    Нет, ни prototype, ни __proto__ не используются в любой момент в качестве плана или около того для создания любого объекта. Это миф, введенный размытым синтаксисом class и его предшественниками. Поскольку ответ-сообщение говорит, что он используется только для поисковой цепочки, а в случае prototype для идентификации constructor, используемого с new (который является частью этого механизма притворяющегося быть классным, который путает многих пользователей включая меня). – Christof Kälin 12 February 2017 в 19:19

'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, тогда конструктор будет вызван новым объектом, в этот процесс «это» будет ссылкой на новый объект в области конструктора, наконец, вернет новый объект.

Прототип конструктора - это свойство __proto__, свойство Constructor prototype работает с new.

Конструктор должен быть функцией, но функция не всегда является конструктором, даже если она имеет свойство prototype.

Цепочка прототипов фактически является свойством объекта __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]] a Свойство nd __proto__ на самом деле то же самое.

Мы можем использовать метод getPrototypeOf объекта, чтобы получить прототип чего-то.

console.log(Object.getPrototypeOf(a) === a.__proto__); // true

Любая написанная нами функция может использоваться для создания объекта с new, поэтому любой из этих функций может быть конструктором.

0
ответ дан 林奕忠 16 August 2018 в 02:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: