js 函数参数 arguments的探究

在js中,函数参数与很多语言的函数参数有所不同,js函数可以在定义时不用申明参数,在调用时,也可以传入参数。如下代码:

function test() {

//各种逻辑

}

test(param1, param2, ...)

这种写法之所以可行,是因为js函数参数内部是使用一个数组来表示的,函数接收到的始终是这个数组,而不关心数组中包含哪些参数。这个数组可以通过自带的arguments参数来访问。

arguments是一个类数组,可以通过arguments[0],arguments[1]...来访问传入的参数,如下代码:

function test() {

console.log(arguments[0] + arguments[1]);//ab

}

test('a', 'b');

可以通过arguments.length来判断传入的参数个数,并进行相应的逻辑,从而达到了方法重载的目的(js本身是没有方法重载的)。如下代码:

function test() {

  if(arguments.length == 1) {

    return arguments[0] + 1;

  }

  if (arguments.length == 2) {

    return arguments[0] + arguments[1];

  }

}

test(1); //2

test(1, 2); //3

如果在函数上申明了参数,那参数与arguments有什么关系呢?来看下面的例子:

例子1:

function test(obj1, obj2) {

  console.log(obj1=== arguments[0]);  //true

  console.log(obj2=== arguments[1]);  //true

}

test({name: 'aa'},  {name: 'bb'})

例子2:

function test(obj1, obj2) {

  num1 = {name: 'newAA', age: 1};

  console.log(obj1);  //{name: "newAA", age: 1}

  console.log(arguments[0]); //{name: "newAA", age: 1}

  console.log(obj1=== arguments[0]);  //true

  arguments[1] = {name: 'newBB', age:2}

  console.log(obj2); //{name: "newBB", age: 2}

  console.log(arguments[1]); //{name: "newBB", age: 2}

  console.log(obj2=== arguments[1]);  //true

}

test({name: 'aa'},  {name: 'bb'})

在<<javascript高级程序设计>>这本书中有在介绍arguments与形参时有这么一段话:

从例子1的结果看,符合书中第一句话的描述,即obj1与arguments[0]都指向同一个内存空间,但从例子2的结果不符合第二句话的描述,当obj1的引用指向新的地址时,arguments[0]也进行了同步!!(若理解有误,希望大家指正);

在严格模式中,这种同步会被禁用,并且不允许修改arguments的值。

posted @ 2018-03-01 16:52  TaurinZeng  阅读(174)  评论(0编辑  收藏  举报