JS中的范围和IIFE:哪些值在功能块之外持续存在?

时间:2016-01-06 17:33:40

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

我正在构建自己的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'

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

3 个答案:

答案 0 :(得分:0)

使用基本类型(字符串,数字等)时,您正在使用它们的值 - 但是对于更高级的数据类型(如数组和对象),您正在使用它们的引用。

我建议阅读本章,它更详细地解释了这些差异:

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

答案 1 :(得分:0)

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

如果StringNumberBoolean值作为参数传递,则保持较早​​值的变量值保持不变。

答案 2 :(得分:0)

你比较错了。您正在执行非常不同的操作。在您的对象示例中,您可以

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将保留21。开始时foo具有哪个值(数字,字符串,对象,......)并不重要。

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

  • 可变
  • 表示为参考

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

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"

由于不变性,"改变"值意味着创建新值。新的价值必须是" put"某处,通常将其分配给同一个变量:

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

换句话说:不可变值迫使我们为变量赋值。