Недоразумение, которое я имею о наследовании прототипа javascript - PullRequest
3 голосов
/ 22 декабря 2010

Простые вопросы.

    function p()
    {
        function A()
        {
            this.random = "random";
        }
        A.prototype.newfunc = function(){ alert("5");}

        function B()
        {

        }

        B.prototype = new A();

        var bObj = new B();
    }

Q1: Когда я устанавливаю прототип B, я не понимаю, как будет обновляться свойство prototype B, когда / если будет обновлен прототип A.Я имею в виду, для меня это просто наследует / копирует все эти свойства.Это не так:

B.prototype = A.prototype

, где B и A - это одно и то же.

Q2: После того, как A возвращается и инициализируется для объекта-прототипа B, как JS узнает, что оно не включает это свойство-прототип?Я имею в виду, что у нас никогда не было таких ситуаций, поскольку интерпретатор JS знает, как просто отрубить свойство прототипа A:

B.prototype = new A(); //any A object has an associated prototype object
    B.prototype.prototype;//after initialization we no longer have the separate prototype property of A

Ответы [ 2 ]

2 голосов
/ 22 декабря 2010

Q1: Вы сказали это сами - прототип используется для наследования.Поэтому B наследует все свойства A. Когда вы добавляете или изменяете члены A, B также изменяется.Как вы правильно сказали, они не одинаковы, но A является суперклассом B, и, если что-то в суперклассе изменится, подкласс также изменится.Тем не менее, вы можете добавить членов в B.prototype и изменить его поведение без изменения A.

попробуйте это:

    function A()
    {
    }

    A.prototype.alertname = function () 
    {
        alert (this.name);
    };

    function B()
    {
    }

    B.prototype = new A();

    var bObj = new B();
    var aObj = new A();

    A.prototype.name = "A"; 
    aObj.alertname(); // output is "A";
    bObj.alertname(); // output is "A";

    B.prototype.name = "B";
    aObj.alertname(); // output is "A";
    bObj.alertname(); // output is "B";

Q2: Опять же, наследование отличается от состава.Когда вы присваиваете B.prototype, вы не просто помещаете объект типа A в заполнитель, но меняете «схему» для всех объектов типа B. Поэтому, когда вы получаете доступ к указанной схеме, вы не получаете объекттипа A, но проект типа B, который содержит ссылку на проект типа A. Этот проект не будет иметь члена типа prototype, так как prototype не является «обычным» членом ни одного из классов.Добавьте это к приведенному выше коду:

function iterateMembers ( obj ) {
    var str = "";
    for (var member in obj) {
        str += member + ", "
    }
    alert (str);
}

iterateMembers (aObj);
iterateMembers (A.prototype); 

Обратите внимание, что ни aObj, ни A.prototype не содержат члена "prototype".Теперь вызовите

iterateMembers (A);
alert (typeof(A));

Теперь должно быть очевидно, что прототип является членом функции типа, и поскольку функция не наследуется ни A, ни B (на самом деле, она не может наследоваться), нииз них содержат член с именем «прототип».

1 голос
/ 22 декабря 2010

Q1: Когда я устанавливаю прототип B, я не понимаю, как будет обновляться свойство prototype B, когда / если будет обновлен прототип A. Я имею в виду, что он просто наследует / копирует все эти свойства.

Объекты функций имеют поле prototype:

function A(name) { this.name = name }

print(A.prototype) // [object Object]

Когда вы создаете объект, используя new A, результирующий объект содержит поле constructor, которое является ссылкой на функцию конструктора:

var a = new A('Eric')

print(a.constructor == A) // True
print(a.constructor.prototype == A.prototype) // True

Если вы попытаетесь проиндексировать a, а поле не определено, JavaScript попытается разрешить его с помощью прототипа a (например, a.constructor.prototype). Мы можем использовать это, чтобы добавить вещи ко всем A экземплярам:

A.prototype.greet = function() { print('Hi, ' + this.name + '!') }

a.greet() // Hi, Eric!

Это разрешение поля работает рекурсивно.

function B(name) { this.name = name.toUpperCase() }
B.prototype = new A
b = new B("Eric")
b.greet() // Hi, ERIC!

В последней строке происходит то, что JavaScript не находит поле 'greet' в b, поэтому он пытается создать прототип b. Там его тоже нет, поэтому он пробует прототип *b и так далее по цепочке, пока у него не закончатся прототипы.

Переводчик знает, как отрубить свойство прототипа А: B.prototype.prototype

Ничего не отрубается, вы просто смотрите не на ту вещь. Вы хотите:

B.prototype.constructor.prototype
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...