javascript管中窥豹 形参与实参浅析(2)


带参数的情况 fn_2(1);
function fn_2(x){//arguments赋值完成,arguments[0]=1。同时形参x有值,两者相关联,永结同心。
var x = 3;//x赋值为3,x与arguments[0]关联,于是arguments[0]被赋值为3,。
console.log(x,arguments[0]);//打印x=3,arguments[0] = 3
arguments[0] = 2;//arguments[0]被赋值2,由于x与arguments[0]已经关联到一起,于是x同时改变
console.log(x,arguments[0]);//打印x = 2,arguments[0]=2
}


反过来应该也是一样的:
不带参数

复制代码 代码如下:


fn_2();
function fn_2(x){//不关联
arguments[0] = 2;//找不到对应的x(undefined),相互独立
console.log(x,arguments[0]);//undefined,2
x = 3;//相互独立,快照。虽然arguments动态添加了,老死不相往来,所以依旧失败
console.log(x,arguments[0]);//3,2
}


带参数

复制代码 代码如下:


fn_2(1);
function fn_2(x){
arguments[0] = 2;//关联
console.log(x,arguments[0]);//2,2
x = 3;//关联
console.log(x,arguments[0]);//3,3
}


由于我们只有一个形参,可能说服力不够,现在增加到两个。
只有一个实参的情况:

复制代码 代码如下:


fn_2(1);
function fn_2(x,y){ //arguments赋值完成,arguments[0]=1,arguments[1]=undefined,因此只有x与arguments[0]关联,y与arguments[1]老死不往来
console.log(x,y,arguments[0],arguments[1]); //1,undefined,1,undefined
var x = 3; //x赋值为3,x与arguments[0]关联,于是arguments[0]被赋值为3。
console.log(x,y,arguments[0],arguments[1]); //3,undefined,3,undefined
var y = 4; //y赋值为3,y与arguments[1]相互独立,arguments[1]还是为undefined
console.log(x,y,arguments[0],arguments[1]); //3,4,3,undefined
arguments[0] = 2; //arguments[0]被赋值2,由于x与arguments[0]已经关联到一起,于是x同时改变
console.log(x,y,arguments[0],arguments[1]); //2,4,2,undefined
arguments[1] = 5; //arguments[1]被赋值5,y与arguments[1]相互独立,于是y还是保持为4
console.log(x,y,arguments[0],arguments[1]); //x=2,y=4,arguments[0]=2,arguments[1]=5
}


有两个实参的情况:

复制代码 代码如下:


fn_3(1,6);
function fn_3(x,y){ //arguments赋值完成,arguments[0]=1,arguments[1]=6,x与arguments[0],y与arguments[1]都相互关联
console.log(x,y,arguments[0],arguments[1]); //1,6,1,6
var x = 3; //x赋值为3,x与arguments[0]关联,于是arguments[0]被赋值为3。
console.log(x,y,arguments[0],arguments[1]); //3,6,3,6
var y = 4; //y赋值为3,y与arguments[1]关联,于是arguments[1]被赋值为4。
console.log(x,y,arguments[0],arguments[1]); //3,4,3,4
arguments[0] = 2; //arguments[0]被赋值2,由于x与arguments[0]已经关联到一起,于是x同时改变
console.log(x,y,arguments[0],arguments[1]); //2,4,2,4
arguments[1] = 5; //arguments[1]被赋值5,由于y与arguments[1]已经关联到一起,于是y同时改变
console.log(x,y,arguments[0],arguments[1]); //x=2,y=5,arguments[0]=2,arguments[1]=5
}


以上全部是推测,因为实际中没有办法形参的信息,所以我按照推测写了一个小测试:
下面的也改了:

复制代码 代码如下:


function _Function(){//获得的形参列表为数组:_args
var _args = [];
for(var i = 0; i < arguments.length - 1; i++){
var obj = {};
obj['key'] = arguments[i];
obj[arguments[i]] = undefined;
_args.push(obj);
}
//this._argu = _args;
var fn_body = arguments[arguments.length - 1];
//下面的方法获取实参_arguments,这里_arguments实现为一个数组,而非arguments对象
this.exec = function(){
//函数运行时,实参_arguments被赋值
var _arguments = [];
for(var i = 0; i < arguments.length; i++){
_arguments[i] = arguments[i];
}
//下面执行函数体
eval(fn_body);
}
}


替换成:

复制代码 代码如下:


function _Function(){//获得的形参列表为数组:_args
var _args = [];
for(var i = 0; i < arguments.length - 1; i++){
var obj = {};
obj['key'] = arguments[i];
obj[arguments[i]] = undefined;
_args.push(obj);
}
//this._argu = _args;
var fn_body = arguments[arguments.length - 1];
//下面的方法获取实参_arguments,这里_arguments实现为一个数组,而非arguments对象
this.exec = function(){
//函数运行时,实参_arguments被赋值
var _arguments = [];
for(var i = 0; i < arguments.length; i++){
_arguments[i] = arguments[i];
}
//在运行开始就判断关联信息
for(var j = 0; j < Math.min(_arguments.length,_args.length); j++){
_args[j]["link"] = true;
}
//下面执行函数体
eval(fn_body);
}
}


上面按理来说,关联应该是把两者指向同一个对象,可是我只需要分析例子,没打算做得那么精细,所以是在函数体里面用if语句判断的 。
把例子中fn_2换成对应的形式就是:

复制代码 代码如下:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wdjjzs.html