的IIFE是爲您提供的唯一事情是一個封閉的範圍。您不需要 多個IIFE,除非您有某些原因未說明。因此,首先,我們介紹一下您閱讀的「最佳實踐」鏈接的真實含義。
在瀏覽器環境中,所有JavaScript都在一個範圍內執行。 因此,下面的兩個腳本將具有相同的範圍,儘管是 不同的文件:
script_a.js
var foo = 'bar'
console.log('foo = ', foo)
script_b.js
if (foo === 'bar') {
console.log('foo is still bar')
}
但是,如果我們換每個腳本在一個IIFE中,範圍變化和script_b
將 不再起作用:
script_a.js
(function() {
var foo = 'bar'
console.log('foo = ', foo)
}())
script_b.js
(function() {
if (foo === 'bar') { // throws an error because `foo` is not defined
console.log('foo is still bar')
}
}())
鑑於網絡發展的性質和jQuery插件使用,許多腳本得到 加載並在全球範圍內得到污染。這可能導致很難識別 副作用。因此建議您在自己的作用域內包含您的代碼。這是通過IIFE完成的,因爲函數有自己的 本地作用域,並且該函數在加載時被調用。
根據您的example,看起來您只需要組合 對象,以便您可以在 開發過程中將它們保留在單個文件中。這是module pattern的明確用法:
script_c。JS
var MY_NAMESPACE = (function() {
var privateFoo = 'foo'
return {
getFoo: function getFoo() {
return privateFoo
}
}
}())
script_d.js
(function (NAMESPACE) {
var privateBar = 'bar'
NAMESPACE.getBar = function getBar() { return privateBar }
}(MY_NAMESPACE))
script_e.js
console.log(MY_NAMESPACE.getFoo()) // 'foo'
console.log(MY_NAMESPACE.getBar()) // 'bar'
注意MY_NAMESPACE
是一個全局變量。這是您必須使用唯一的 ,因爲它可能會被覆蓋您的全局變量的稍後加載的腳本覆蓋。
我還沒有使用它,但有一個庫叫做stampit, 擴展到這種模式,並使它易於使用。
與所有的這麼說,然後你可以擴展你的MY_NAMESPACE
對象爲 一個新的對象:
script_f.js
var CHILD_NAMESPACE = Object.create(MY_NAMESPACE)
CHILD_NAMESPACE.fooOrBar = (function (NS) {
var counter = 0
return function() {
var answer = (counter % 2 === 0) ? NS.getFoo() : NS.getBar()
counter += 1
return answer
}
}(CHILD_NAMESPACE))
當然,以上所有的腳本可以包含在一個單一的整體 IFFE完全包含您的代碼在自己的範圍內。
因此,這樣做的話,我會在父級中擁有所謂的* getter *,並且就像例子中的兒童類中的* setter *一樣?另外,我是否能夠訪問父上下文中的變量,而無需通過預先登錄對象名稱來公開它們?憑藉我對JavaScript的瞭解,看起來不錯,但是這是一種有效的做法嗎? – user5613506
對我來說,沒有這樣的最佳或有效的做法,如果它適合我們,然後簡單地使用它:)。最後,JavaScript不是一種OOP語言,試圖編寫像編碼C#一樣的JS,Java最終會失去語言的優勢。 – phnkha
最近我工作的是這個,但它看起來更像是一個浮誇的依賴注入,而不是繼承給我,畢竟,因爲我注入了這裏所謂的基礎對象,我可以直接使用'Base.getFoo()''而不是'Child.prototype.getFoo()' – user5613506