JavaScript奇葩的参数机制

今天实习生遇到一个问题,以前没碰到过,笔记一下。

今天实习生遇到一个问题:有一个数组,想在一个函数里将它清空,结果办不到。代码大概是这样的:

function empty(arr) {
  arr = [];
}
var array = [1, 2];
empty(array);
console.log(array); // 预期 [],实际 [1, 2]

对于我这种半路出家根基不实的人来说面对这种问题总是很挠头。于是只有翻书,在《JavaScript高级程序设计(第三版)》上看到,原来JavaScript的函数参数设计这么奇葩。

首先,JS里的变量分为值类型和引用类型,这点我是知道的。基础类型只有NaN、null、undefined、String、Number这5个,其他都是引用类型,也就是赋值时传引用不复制值的类型。区分如下:

// 值类型
var a = 'test',
    b = a;
b = 'temp';
console.log(a); // 'test'

// 引用类型
var a = {id: 1},
    b = a;
b.id = 2;
console.log(a.id); // 2

但是在用在函数参数的时候,又会有所不同。参数并不是传递的引用,而是传递的引用的引用。所以即使用“===”判断,也会返回true,因为最终指向的对象是一样的。但是如果在参数中对参数重新赋值的话,就相当于改变了引用地址,重新创建了一个对象,也就无法操作外面的对象了。这可能也是“运行时环境对象”造成的结果吧。