Javascript: переменная из [пользовательский прототип] недоступна - PullRequest
1 голос
/ 12 августа 2011

Я играю в javascript с книгой Профессиональный JavaScript для веб-разработчиков .Я практикую пример в разделе 6.2.6.коды перечислены ниже:

function creatPrototype(subType, superType) 
{
    function subTypePrototype(){};
    subTypePrototype.prototype = superType.prototype;
    subTypePrototype.constructor = subType;
    subTypePrototype.str = "say";
    return new subTypePrototype();
}

function Person(name, age) 
{
    this.name = name;
    this.age = age;
}
Person.prototype.say = function(){
    writeln("bill say");
}


function itMan(name, age){
    Person.apply(this, arguments); 
}
itMan.prototype = creatPrototype(itMan, Person); 


var Bill = new itMan("bill", 25);

writeln(itMan.prototype.str);    //expect "say"
writeln(Person.prototype == itMan.prototype.prototype);   //expect true
Bill.say();  //expect "bill say"

результат:

undefined

Неверно

Билл скажет

Почему?

  1. itMan.prototype.str предполагается "сказать"

  2. Person.prototype AND itMan.prototype.prototype должен указывать на тот же объект

  3. Bill.say () работает правильно, поэтому цепочка прототипов в порядке.

Ответы [ 3 ]

2 голосов
/ 12 августа 2011

Вы должны подумать о том, какое свойство принадлежит функции конструктора , а какое принадлежит экземпляру .prototype является свойством функции, но constructor и str должны быть оба свойства экземпляра.

Это должно сделать это:

function createPrototype(subType, superType) 
{
    function subTypePrototype(){};
    subTypePrototype.prototype = superType.prototype;

    var newPrototype = new subTypePrototype();

    newPrototype.constructor = subType;
    newPrototype.str = "say";
    return newPrototype;
}

Но, как вытакже можно передать subType, вы можете назначить прототип напрямую:

function inherit(subType, superType) 
{
    function tconstr(){};
    tconstr.prototype = superType.prototype;

    subType.prototype = new tconstr();

    subType.prototype.constructor = subType;
    subType.prototype.str = "say";
}

, а затем просто вызвать его с помощью

inherits(itMan, Person);

Person.prototype AND itMan.prototype.prototype должен указывать на один и тот же объект

Помните, что prototype является свойством функции , а не объектов.Но itMan.prototype это объект.Вы не можете получить доступ к прототипу объектов, если вы явно не обращаетесь к нему (но я бы не стал этого делать).

В ECMAScript 5 есть способ получить прототип, используя Object.getPrototypeOf [MDN] .Это работает только в новых браузерах.

Вот рабочий пример вашего кода.

1 голос
/ 12 августа 2011

Произошла ошибка с кодом, попробуйте этот код

function creatPrototype(subType, superType) 
{
    function subTypePrototype(){
    this.prototype = superType.prototype;
    this.constructor = subType;
    this.str = "say";
}


    return new subTypePrototype();
}

function Person(name, age) 
{
    this.name = name;
    this.age = age;
}
Person.prototype.say = function(){
    document.writeln("bill say");
}


function itMan(name, age){
    Person.apply(this, arguments); 
}
itMan.prototype = creatPrototype(itMan, Person); 


var Bill = new itMan("bill", 25);

document.writeln(itMan.prototype.str);    //expect "say"

document.writeln(Person.prototype == itMan.prototype.prototype);   //expect true
Bill.prototype.say();  //expect "bill say"

В вашем коде вы не использовали this объект, поэтому itMAn не имеет переменной str, вы использовали subTypePrototype.constructor = subType; и subTypePrototype.prototype = superType.prototype; следовательно, Bill.say работал, а Person.prototype == itMan.prototype.prototype не работал.

0 голосов
/ 12 августа 2011

Prototype - это зарезервированное ключевое слово, и вы должны быть очень осторожны при его использовании. Статьи по ключевому слову прототипа

У вас есть несколько проблем в вашем коде.

Тогда внутри вашего createSubPrototype:

return new subTypePrototype();

Вы создаете функцию, а затем возвращаете результат выполненной функции, где вы должны вернуть указатель на вашу функцию, например

return subTypePrototype;

Но вы не должны создавать функцию, потому что кажется, что вы хотите получить родительский «прототип»:)

Таким образом, ваш код должен выглядеть примерно так:

function createPrototype(subType, superType) 
{
  subTypePrototype = superType.prototype;
  subTypePrototype.constructor = subType; //- beware this is wrong !!!
  subTypePrototype.str = "say";
  return subTypePrototype;
}

Проверьте строку, которую я пометил как неправильную, тем самым вы обновляете как вспомогательный, так и родительский тип

Как это сделать: При этом, если вы хотите расширить объект, я бы посоветовал вам использовать существующие библиотеки. (jQuery, Mootools и т. д.). Вот пример того, как это сделать правильно

...