Javascript: наследование прототипа и свойство прототипа - PullRequest
4 голосов
/ 14 марта 2010

У меня есть простой фрагмент кода в JS, работающий с наследованием прототипа.

function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}

//the following code block has a alternate version
var mammal = {
    color: "brown",
    getColor: function() {
        return this.color;
    }
}

var myCat = object(mammal);
myCat.meow = function(){return "meow";}

, который работал нормально, но добавив:

mammal.prototype.kindOf = "predator";

нет. ( "млекопитающий. Прототип не определен" )

Так как я догадался, что у объекта, возможно, нет прототипа, я переписал его, заменив блок var mammal = {... на:

function mammal() {
    this.color = "brown";
    this.getColor = function() { return this.color; }
}

, который дал мне кучу других ошибок:

"Function.prototype.toString вызвано для несовместимого объекта"
и если я пытаюсь вызвать _myCat.getColor ()
«myCat.getColor не является функцией»


Теперь я в полном замешательстве. После прочтения Крокфорда и Фланагана я не получил решения по ошибкам. Так что было бы здорово, если бы кто-то знал ...

- почему прототип не определен в первом примере (это самое главное; я думал, что прототип явно задан в функции object () )

- почему я получаю эти странные ошибки, пытаясь использовать функцию млекопитающего в качестве объекта-прототипа в функции object () ?

Редактирование создателем вопроса: Эти две ссылки тоже очень помогли:

Prototypes_in_JavaScript в вики сферодева объясняет, как свойство прототипа работает относительно просто. Чего не хватает, так это нескольких примеров кода. Некоторые хорошие примеры приводятся в статье Морриса Джона . Я лично считаю, что объяснения не так просты, как в первой ссылке, но все же очень хорошо. Самая сложная часть, даже после того, как я ее получил, это на самом деле не путать свойство .prototype с внутренним [[Prototype]] объекта.

1 Ответ

5 голосов
/ 14 марта 2010

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

Я думаю, вы путаете это свойство с внутренним свойством [[Prototype]].

Свойство [[Prototype]] может быть установлено только оператором new через внутреннюю операцию [[Construct]].

Это свойство недоступно (хотя есть несколько способов, например, в реализации Mozilla с помощью obj.__proto__; или нового метода ECMAScript 5 Object.getPrototypeOf).

По второму вопросу вы получаете эти ошибки, потому что вы создаете новый объект, который наследуется от функции, а не от другого объекта.

А как же:

var mammal = {
  color: "brown",
  getColor: function(){
    return this.color;
  },
  kindOf: "mammal" // "base" value
};
// ...
var tiger = object(mammal);
tiger.roar = function(){return "roar";}
tiger.kindOf = "predator"; // specific value

В приведенном выше фрагменте все экземпляры, наследуемые от mammal, будут иметь свойство kindOf, которое вы сможете изменить позже при создании более конкретных млекопитающих объектов.

Редактировать: В ответ на ваш комментарий, да, сам язык дает вам инструмент, чтобы узнать, что метод Object.prototype.hasOwnProperty возвращает логический результат, указывающий, является ли объект физически имеет указанное свойство или нет, например:

var obj = {
  foo: 'bar'
};

obj.hasOwnProperty('foo'); // true
obj.hasOwnProperty('toString'); // false, inherited from Object.prototype

Вы также можете вызывать этот метод непосредственно на Object.prototype, поэтому, если кто-то назовет свойство hasOwnProperty для объекта, он не будет завершен:

Object.prototype.hasOwnProperty.call(obj, 'foo'); // true
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...