【问题标题】:Scope and IIFEs in JS: which values persist outside function block?JS 中的范围和 IIFE:哪些值在功能块之外持续存在?
【发布时间】:2016-04-10 21:37:01
【问题描述】:

我正在构建自己的 jQuery 插件,并且想知道 $ 对象的更改如何在 IIFE 之外持续存在:

(function($){
  //plugin
 }(jQuery);

所以我玩了一个 JS REPL,发现对象和数组的更改在 IIFE 之外仍然存在,但字符串的更改不会:

var obj={a:1,b:2};

(function(obj){obj.c=3})(obj);

**obj**
{ a: 1, b: 2, c: 3 }

arr=[1,2]
[ 1, 2 ]

(function(arr){arr.push(3)})(arr);

**arr**
[ 1, 2, 3 ]

str='aoeu'
'aoeu'

(function(str){str+='aoeu'})(str);

**str**
'aoeu'

有人可以向我解释一下对象、数组和字符串之间的区别吗?

【问题讨论】:

  • 因为字符串是原始的,函数中的str函数之外的str有不同的引用。这意味着+= 运算符永远不会触及外部标识符的值。如果你熟悉其他语言,如果typeof foo; // "object" 则参数为ByRef,否则为ByVal
  • 这与 IIFE 无关;您可能需要修正问题的标题。

标签: javascript pass-by-reference pass-by-value


【解决方案1】:

当您使用原始类型(字符串、数字等)时,您使用的是它们的值 - 但是使用更高级的数据类型(如数组和对象)时,您使用的是它们的引用。

我推荐阅读这一章,它更详细地解释了不同之处:

http://docstore.mik.ua/orelly/webprog/jscript/ch11_02.htm

【讨论】:

    【解决方案2】:

    当传递的typeOf 参数是ArrayObject 类型时,则传递值的引用(指针)而不是value。因此,如果引用被更新,则意味着 reference 持有的值被更新。

    StringNumberBoolean 值作为参数传递的情况下,因此保存较早值的变量的值保持不变。

    【讨论】:

      【解决方案3】:

      你的比较是错误的。您正在执行非常不同的操作。在您的对象示例中,您会这样做

      obj.c = 3
      

      您正在读取来自obj 并改变对象。您不是在创建新对象。

      在您的字符串示例中,您可以这样做

      str += 'aoeu'
      

      您在此处写入str,用新的字符串值覆盖其先前的值。这与您对对象所做的操作完全不同。

      如果您对对象执行相同的操作,您会得到类似的结果。等价的例子宁愿像

      obj = {a: obj.a, b: obj.b, c: 4};
      

      为变量分配新值从不更新另一个变量的值:

      var foo = 42;
      var bar = foo;
      foo = 21;
      

      bar 将保留21foo 开头的值(数字、字符串、对象……)并不重要。

      但是,对象有两个方面需要理解:对象是

      • 可变
      • 表示为参考

      这意味着如果您有一个对象并将其分配给另一个变量:

      var foo = {};
      var bar = foo;
      

      foobar 现在指向内存中的同一个对象。因为对象是可变的,它们可以“就地”改变:

      bar.x = 5;
      console.log(foo.x);
      

      原始值(任何不是对象的东西)是不可变的。它们不能原地更改:

      var foo = "abc";
      foo[0] = "x";
      console.log(foo); // still "abc", not "xbc"
      

      由于不变性,“改变”一个值意味着创建一个新值。该新值必须“放置”在某处,通常是将其分配给同一个变量:

      foo = 'x' + foo.substring(1);
      

      或者换句话说:不可变的值迫使我们为变量分配新的值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-04-03
        • 1970-01-01
        • 2014-02-14
        • 2012-09-14
        • 1970-01-01
        • 2018-02-22
        • 1970-01-01
        • 2021-08-24
        相关资源
        最近更新 更多