使用IIFE进行JavaScript对象继承?

时间:2017-01-03 14:14:26

标签: javascript jquery oop iife

我不会说谎我对JavaScript很棒,也不是我理解IIFE概念,但是自从我阅读Chris's answer然后首先遇到这个概念加上后来进行的一些研究后,我走到了这样:

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

    var privateVariable = {};

    MyObject.publicVariable;

    function privateMethod() {}

    myObject.publicMethod() {}

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

虽然它按预期工作得很好,但我最近觉得需要某种形式的抽象,所以我可以创建一个带有共享属性和方法的基类以及具有自己逻辑的子对象。

这样我就不需要,比方说,重复每个单独对象中所有孩子共同的 getter

我当然搜索过这个问题,但是我没有找到关于如何用这个概念实现这个功能的具体信息。

2 个答案:

答案 0 :(得分: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 ) );

答案 1 :(得分: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')
  }
}())

鉴于Web开发的本质,以及带插件的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在自己的范围内完全包含您的代码。