2015-04-04 4 views
0

Я пытаюсь использовать атрибут функции во вложенной функции, но я не знаю, как, не передавая родительскую функцию.Наследование атрибута вложенной функции Javascript

пример:

function foo() { 
    this.baz = 'baz' 
    this.bar = new bar() 
} 

function bar() { 
    this.bla = 'bla' 
} 

bar.prototype.func = function() { 
    console.log(...) // this should return 'baz' (attr baz of foo()) 
} 

До сих пор я судимое это:

function foo() { 
    this.baz = 'baz' 
    this.bar = new bar(this) 
} 

function bar(foo) { 
    this.bla = 'bla' 
    this.foo = foo 
} 
bar.prototype.func = function() { 
    console.log(this.foo.baz) 
} 

Есть хороший шаблон для достижения этой цели? так как мой обходной беспорядок

EDIT:

Поскольку некоторые из вас хотели больше RealLife exapmle:

function Game() { 
    this.world = { 
     x: 200, 
     y: 300 
    } 
    this.players = { 
     one: new Player() 
     two: new Player() 
    } 
} 

function Player() { 
    this.size = {x:1,y:2} 
    this.position = { 
     x: world.x - this.size.x, // i need to access games world attribute 
     y: 0 
    } 
} 

Но это не единственный атрибут класса игры мне нужно в класс игрока ..

+0

Это похоже на половину вопроса о том, как работает область обзора JavaScript, и половина вопроса о том, как работает наследование. Возможно, если вы дадите более реальный пример, мы могли бы сделать лучшие предложения для * хорошего * способа сделать то, что вы пытаетесь сделать. В настоящее время мой ответ будет «просто передать ссылку' foo' на 'bar'. – brianvaughn

+0

В вашем примере« bar »не наследуется от' foo'. На «bar» нет прототипа атрибута, который может получить доступ Свойства 'foo'. То, что вы делаете в первом примере, может быть рассчитано на * зависимую инъекцию *, но не наследование вообще. Что касается второго примера, то также нет наследования, но вы используете' bar' as декоратор 'foo', так что вы можете сделать' this.foo.baz'. Это совершенно верно для этой реализации декоратора. – amenadiel

+0

Я с @brianvaughn - текущий кажется прекрасным, однако это может быть не в зависимости на реальную потребность, и может быть, действительно, лучший способ. – vlaz

ответ

1

Обновленный ответ

Вы можете прочитать о encapsulation. Учитывая Ваш обновленный пример, было бы разумно для вас, чтобы передать ссылку на Game для каждого из ваших Player экземпляров так:

function Game() { 
    this.world = { 
     x: 200, 
     y: 300 
    } 
    this.players = { 
     one: new Player(this), 
     two: new Player(this) 
    } 
} 

function Player(game) { 
    this.game = game; 
    this.size = {x:1,y:2} 
    this.position = { 
     x: game.world.x - this.size.x, // i need to access games world attribute 
     y: 0 
    } 
} 
Player.prototype.anotherFunction = function() { 
    console.log(this.game); // Also has access to `this.game` 
} 

Как Vld @ говорит, есть, вероятно, более эффективные способы сделать то, что вы пытаетесь в этом примере, но я подозреваю, что это более общий вопрос.

Оригинальный ответ

Один из способов сделать то, что вы пытаетесь сделать бы с наследованием, например, так:

function Foo() { 
    this.baz = 'baz'; 
} 
function Bar() { 
    this.bla = 'bla'; 
    Foo.call(this); 
} 
Bar.prototype = Object.create(Foo.prototype); 

console.log(new Bar().baz); // "baz" 
+0

спасибо за ваш ответ. как насчет использования «игры» в прототипе игроков? я могу использовать его там тоже? –

+0

Я не уверен, что понимаю ваш вопрос. Но ... Я обновлю свой ответ, чтобы отразить то, что я * думаю *, вы просите – brianvaughn

+0

, да, это именно то, о чем я просил. но теперь вам нужно было сохранить экземпляр игры в атрибуте, который я уже имел. так что если это лучший способ, мой вопрос в ответе. Спасибо за вашу помощь! –

0

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

function Game() { 

    // Declare private variables as 'var' here 

    this.world = { 
     x: 200, 
     y: 300 
    } 
    this.players = { 
     one: new Player() 
     two: new Player() 
    } 

    // The following players methods will have access to 
    // both public and private interface of Game 
    this.players.one.position = { 
     x: this.world.x - this.players.one.size.x, 
     y: 0 
    } 
    this.players.two.position = this.players.one.position; 
} 

function Player() { 
    // Declare private variables for player as 'var' here 

    this.size = {x:1,y:2} 
} 
+0

и как насчет аттрибутов, которые мне нужны в прототипе игрока? –

+0

Если вашему прототипу игрока нужен какой-либо атрибут, вы должны передать его как параметр конструктору, например, этот «один: новый проигрыватель (спецификации)» (предполагая, что ваши прототипы построены с использованием _this_) – Roger

Смежные вопросы