улучшить наследование прототипа javascript - PullRequest
1 голос
/ 11 июня 2010

Я использую классическое наследование прототипов javascript, например:

function Foo() {}   
Naknek.prototype = {
//Do something
};
var Foo = window.Foo = new Foo();

Я хочу знать, как я могу улучшить это и почему я не могу использовать эту модель:

var Foo = window.Foo = new function() {
};
Foo.prototype = {
//Do something
};

Почему этот код не работает? В моей голове это более логично, чем классическое наследование прототипов.

Ответы [ 3 ]

9 голосов
/ 11 июня 2010

Ваш var Foo = window.Foo = new Foo(); пример ... странный. Сначала вы объявляете функцию Foo, затем назначаете что-то ее прототипу (я предполагаю, что вы хотели заменить Nannak на Foo во второй строке), а затем вы перезаписываете ссылку на функцию, присваивая ей.

Стандартное прототипическое наследование Javascript выглядит так:

// Create a constructor `Foo`
function Foo() {
}

// Give the prototype for `Foo` objects a function bound to the
// property `bar`
Foo.prototype.bar = function() {
}

// Only do this bit if you're doing this within a function and you want
// to make `Foo` available as a property of `window` (e.g., effectively
// a global variable. If this code is already at global scope, there's
// no need to do this.
window.Foo = Foo;

Вот как бы вы использовали Foo:

// Create a `Foo` and use its `bar`
var f = new Foo();
f.bar();

Пара других заметок:

  • Никогда не используйте new function() { ... }, если вы действительно, действительно не знаете, что делаете. Он создает объект, инициализированный функцией, но не создает новую функцию. Почти нет необходимости в подобном (но полностью отличается) new Function(...), опять же, за исключением некоторых сложных случаев.
  • Функция, связанная с bar в моем примере выше, является анонимной (свойство, с которым она связана, имеет имя, но функция не имеет). Я не фанат анонимных функций, но я не хотел загромождать приведенный выше пример. Подробнее здесь.
  • Если вы используете var в глобальном масштабе (из вашего вопроса не было ясно, были ли вы), он создает свойство для объекта window. Вам нужно будет сделать var Foo = window.Foo = ..., только если вы находитесь внутри функции и хотите, чтобы и создали множество window и создали локальную переменную с именем Foo. (Что, возможно, ты хотел сделать! :-))
  • Способ присвоения прототипов свойств Foo.prototype = { .. }; работает, но, как правило, это не очень хорошая идея (опять же, если вы не очень разбираетесь в этом материале). Когда вы делаете это, вы полностью заменяете объект-прототип, используемый при вызове функции через new, тогда как если вы просто добавляете к ней свойства (Foo.prototype.bar = ...), вы просто увеличиваете прототип, не заменяя его. Замена прототипа вполне допустима, но есть некоторые неочевидные вещи, которые могут произойти, если вы неосторожны. : -)
2 голосов
/ 11 июня 2010

Вы используете оператор new в выражении функции, который заставляет вновь созданный объект присваиваться window.Foo.

Этот новый объект не является функцией , поэтому он не имеет свойства prototype и не может быть вызван.

1 голос
/ 11 июня 2010

«не работает» является расплывчатым, но я думаю, что основная причина - new function() { (new здесь не относится)

Вы, вероятно, хотите:

var Foo = window.Foo = function() {
};
Foo.prototype = {
  bar: 'baz'
};

alert(new Foo().bar); // baz
...