2013-05-30 121 views
8

我一直在閱讀HTML5和JavaScript的遊戲設計,它介紹了我的對象。因此,在閱讀本書並開展項目工作之後,我決定採用這些新的知識,並將對象集成到自己的項目中。所以這裏是我的問題可以或應該對象調用自己的功能?例如:JavaScript對象調用函數本身

var someObject = { 
    start: function() { 
     check(); 
    }, 
    check: function() { 
     console.log("Check!"); 
    } 
}; 

someObject.start(); 

這本書確實顯示出有做這個計時器的例子:

var timer = { 
    start: function() { 
     var self = this; 
     window.setInterval(function(){self.tick();}, 1000); 
    }, 
    tick: function() { 
     console.log('tick!'); 
    } 
}; 

與定時器對象是爲了調用內部功能,使自我參照的例子,這意味着我應該使用self來調用內部函數,或者這是用對象來做到這一點的正確方法嗎?還是最佳做法?提前致謝。

var someObject = { 
    start: function() { 
     var self = this; 
     self.check(); 
    }, 
    check: function() { 
     console.log("Check!"); 
    } 
}; 

someObject.start(); 
+3

他們使用它在'setTimeout'例子的原因是因爲它的回調在全球範圍內執行的,所以'this'在'setTimeout'值回調是'window'。爲了保持對原始對象的引用,你必須使用該方法(將其存儲在'self'中)或某種形式的使用'Function.bind()' – Ian

回答

5

JavaScript的名字是lexically scoped,所以每當一個名稱(變量)在腳本中遇到的JavaScript運行必須搜索了從定義功能在範圍。

在定義的角度來看,這一功能:

start: function() { 
    check(); 
} 

沒有訪問任何check功能在其外部範圍。聲明self並將其綁定到this是一種用於處理(有點有趣)intricacies of referring to the current object in JavaScript(因爲示例代碼使用window.setInterval)的技術。

要引用函數當前對象內,它是足夠使用this

var someObject = { 
    start: function() { 
     this.check(); 
    }, 
    check: function() { 
     console.log("Check!"); 
    } 
}; 
0

當然,一個對象可以並應該調用它自己的函數,這是在JavaScript中模擬OOP的唯一方法。我會說,這本書使用的做法,self = this是壞的,因爲this可以自己使用,但在第一個例子中,它被用來保存這本來的價值,否則會是該函數本身的this而不是外部類

+0

「模擬」;只是不斷地告訴自己,也許在你說出來時點擊你的腳後跟...... – dandavis

+0

做var self = this'有多種原因;一個完全不相關的原因是使腳本壓縮更有效率。 – voithos

+0

@voithos閱讀整個答案我只說第二次使用不好 – aaronman

1

聲明和初始化像「自我」這樣的變量的意義在於處理在每次函數調用時重新確定值this的事實。當你有一個嵌套在另一個函數內部的函數,並且內部函數需要從外部上下文訪問this的值時,那麼this必須保存在另一個變量—「self」中。 (該變量的名稱是不重要的,當然。)

在您的示例代碼:

var timer = { 
    start: function() { 
     var self = this; 
     window.setInterval(function(){self.tick();}, 1000); 
    }, 
    tick: function() { 
     console.log('tick!'); 
    } 
}; 

該函數傳遞給setInterval()需要從「開始」功能使用的this值。但是,當調用間隔定時器功能時,this被設置爲其他內容(全局上下文或「嚴格」模式下的null)。因此,通過在實例化該間隔計時器函數的上下文中將this的值保存,其代碼可以使用它來訪問計時器對象。

在你的第二個例子中,聲明和初始化一個「自我」變量不會傷害任何東西,但它是不必要的。有時候,這很方便,但只是爲了澄清代碼,儘管當然比「自我」更有意義的名字將是一個好主意。

+0

這不是在第二個例子中正在做什麼,雖然 – aaronman

+0

@aaronman是的,這是真的。 – Pointy

1

這是javascript函數上下文,每次創建函數時,都會創建一個新的上下文(範圍)。

setInterval()函數創建一個新的範圍,所以this不再引用一樣this以上:

var self = this; 
setInterval(function() { 
    self.tick(); 
}, 1000); 

您也可以手動將功能的適當的範圍內綁定bind()(讓你不需要self了):

setInterval(function() { 
    this.tick(); 
}.bind(this), 1000); 

更多信息: