2017-01-03 174 views
1

我不會說謊,我真棒用JavaScript也不是說我理解它的整體的IIFE概念,但因爲我讀jQuery Best Practices,然後第一次見面的概念加上一些研究後提出,我想出了這個:JavaScript對象繼承與IIFE?

(function(MyObject, window, document, $, undefined) { 

    var privateVariable = {}; 

    MyObject.publicVariable; 

    function privateMethod() {} 

    myObject.publicMethod() {} 

}(window.MyObject = window.MyObject || {}, window, document, window.jQuery)); 

雖然它能很好地工作,但我最近覺得需要某種形式的抽象,所以我可以創建一個具有共享屬性和方法的基類以及具有自己邏輯的子對象。

這樣我就不需要,讓我們說,重複吸氣共同所有的孩子在每個單獨的對象。

我已經搜索了關於這個問題,當然,但我沒有找到關於如何實現這個概念的特性的具體信息。

回答

1

如何使用施工方法:

(function(MyObject, window, document, $, baseClass) { 

    // calling base class for common properties, methods 
    baseClass && baseClass.call(MyObject); 

    var privateVariable = {}; 

    MyObject.publicVariable; 

    function privateMethod() {} 

    myObject.publicMethod() {} 

}(window.MyObject = window.MyObject || {}, window, document, window.jQuery, baseClass)); 
+0

因此,這樣做的話,我會在父級中擁有所謂的* getter *,並且就像例子中的兒童類中的* setter *一樣?另外,我是否能夠訪問父上下文中的變量,而無需通過預先登錄對象名稱來公開它們?憑藉我對JavaScript的瞭解,看起來不錯,但是這是一種有效的做法嗎? – user5613506

+0

對我來說,沒有這樣的最佳或有效的做法,如果它適合我​​們,然後簡單地使用它:)。最後,JavaScript不是一種OOP語言,試圖編寫像編碼C#一樣的JS,Java最終會失去語言的優勢。 – phnkha

+0

最近我工作的是這個,但它看起來更像是一個浮誇的依賴注入,而不是繼承給我,畢竟,因爲我注入了這裏所謂的基礎對象,我可以直接使用'Base.getFoo()''而不是'Child.prototype.getFoo()' – user5613506

0

的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完全包含您的代碼在自己的範圍內。