原型变量没有被构造函数覆盖

时间:2017-01-13 17:25:37

标签: javascript

我正在尝试允许init函数覆盖默认设置,但由于某种原因,它只使用本地设置,任何人都可以解释为什么以及如何解决这个问题。

var obj = (function() {
  var settings = {
    height : 10,
    width : 20
  };

  function init(settings) {
    this.settings = settings
    setObj()
  }

  function setObj() {
    if (settings.height == 0) {
      console.log('good height')
    } else {
      console.log('bad height')
    }
  }
  return {
    init : init,
  }
})()

var settings = {
    height : 0,
    width : 20
  };
obj.init(settings);

3 个答案:

答案 0 :(得分:1)

而不是var使用this.settings

var obj = (function() {
  this.settings = {
    height : 10,
    width : 20
  };

  function init(settings) {
    this.settings = settings
    setObj()
  }

  function setObj() {
    if (settings.height == 0) {
      console.log('good height')
    } else {
      console.log('bad height')
    }
  }
  return {
    init : init,
  }
})()

var settings = {
    height : 0,
    width : 20
  };
obj.init(settings);

答案 1 :(得分:0)

这里的init函数是一个闭包,即使在IIFE执行之后,init也引用了局部变量。首先,它检查设置对象的height属性是否在本地可用并获取值。但是当我们使用这个关键字时,它指的是init函数的设置,它引用了全局设置对象。如果我错了,请纠正我。

some text here some text here some text here some text here
<br>
some text here some text here 
<br>
some text here some text here some text here some text here


some text here some text here some text here some text here
<br>
some text here some text here 
<br>
some text here some text here some text here some text here


some text here some text here some text here some text here
<br>
some text here some text here 
<br>
some text here some text here some text here some text here

答案 2 :(得分:0)

我不确定你要做什么,但你的问题是帮助人们理解模块和revealing module pattern.

的一个很好的例子

目前,当您执行IIFE时,它返回到obj变量/ Module的唯一值是一个匿名对象,其方法为init

return {  // <-- anonymous object returned with all its properties available!
    init : init 
}

因此绑定到返回对象的方法现在可用于模块的命名空间,即obj。其他一切都是私密的,即var settings (object), the setObj, (function object)

想想这部分可能令人困惑:

function init(settings) {
    this.settings = settings
    setObj()
} 

当您致电init时,会向obj Module添加 new 属性。那是因为当你调用:

obj.init(settings);

this关键字指向返回的对象,该对象已分配给obj名称空间/模块。

要在调用IFFE之后证明它,但在之前在模块上调用init,请运行:

console.dir(obj);
  

调用console.dir(object)将记录一个的交互式列表   对象的属性,例如&gt; DOM选项卡的缩小版

基本上你将获得obj的所有属性。此时它只是初始化。

重申一下,您的init不会覆盖settings变量,即IIFE中分配给obj的变量,该变量无法访问(除非您使用 public方法来更新它)。您的init会向IIFE返回的对象添加属性。

我在您的模块中添加了一个名为checkSettings的函数,并更改了您的init函数。我创建了checkSettings,因此您可以在运行init之前和之后看到settings obj,基本上您可以直接看到更改。如果名称匹配,我的init只会覆盖属性。

var obj = (function() {

  var settings = {
      height : 10,
      width : 20
  };

  function init(objProps) {
      for (var p in objProps) {
          if(settings.hasOwnProperty(p)) {
              settings[p] = objProps[p];
          }
      }
      setObj()
   }

  function checkSettings(){
     console.log('The following properties and values are on settings object');     

     for(var p in settings) {
        if(settings.hasOwnProperty(p)) {
          console.log(p + ' ' + settings[p]); 
        }
     }
  }

  function setObj() {
    if (settings.height == 0) {
      console.log('good height')
    } else {
      console.log('bad height')
    }
  }
  return {
    init : init,
    checkSettings : checkSettings
  }
})()

希望这有用!