2015-04-04 89 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()) 
} 

到目前爲止我tryed這一點:

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) 
} 

是否有一個良好的模式來做到這一點?因爲我的解決方法是一個爛攤子

編輯:

由於一些你想要一個更現實生活中的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 
    } 
} 

但這不是遊戲類我需要的唯一屬性Player類..

+0

這似乎是關於JavaScript範圍如何工作的一半問題,以及關於繼承如何工作的一半問題。也許如果你給了更多的現實生活中的例子,我們可以提出更好的建議,以便做出你想做的事情。現在看來,我的迴應是「僅僅通過一個'foo'引用'bar' – brianvaughn 2015-04-04 16:25:03

+0

在你的例程中,'bar'不會從'foo'繼承,'bar'上沒有可以訪問的原型屬性'foo'的屬性,你在第一個例子中做的事情可能相當於* dependency injection *,但是沒有任何繼承關於第二個例子,也沒有繼承,但是你使用'bar'作爲一個'foo'的裝飾器,所以你可以做'this.foo.baz',這對裝飾器的實現來說是完全有效的。 – amenadiel 2015-04-04 16:26:10

+0

我與@brianvaughn - 目前看起來很好,但它可能不會取決於根據實際需要,確實有更好的辦法 – vlaz 2015-04-04 16:26:18

回答

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

感謝您的答案。在玩家原型中使用「遊戲」怎麼樣?我可以在那裏使用它嗎? – 2015-04-04 16:45:16

+0

我不確定我瞭解你的問題。但是...我會更新我的答案,以反映我認爲你問的是 – brianvaughn 2015-04-04 16:46:11

+0

是的,這正是我所要求的。但現在你必須將遊戲實例存儲在一個屬性中,這就是我已經擁有的屬性。所以如果這是我回答問題的最佳方式。謝謝你的幫助! – 2015-04-04 16:49:30

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

以及我在玩家原型中需要的屬性呢? – 2015-04-07 07:06:06

+0

如果你的玩家原型需要任何屬性,那麼你應該把它作爲參數傳遞給構造函數,就像這個'one:new Player(specs)'(假設你的原型方法是用_this_構建的) – Roger 2015-04-09 01:37:44