的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