2017-01-03 140 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完全包含您的代码在自己的范围内。