Hardog's blog

trace forever

Group: 572218159
Email: 1273203953@qq.com
Location: hangzhou·zhejiang
GitHub: https://github.com/hardog

本文目标

本文测试环境

函数传参类型

js函数的参数可以分为两种类型:

基本类型的传参

对于基本类型的参数传递,在js语法中采用的是按值传递求值策略,即对于传入函
数中的基本类型的值,传入函数内部时,会对传入的参数拷贝一份副本然后对副本进行操作,如下所示:

1
var fn = function(param){
    // 对param进行修改
    param = 4;
};

var param1 = 12;
console.log('before call fn:'+param1);
fn(param1);
console.log('after call fn:'+param1);

结果如下:
按值传递
可见调用函数前后并不会对基本类型值param1产生影响,即按值传递并不会修改传入
函数的基本类型值。

对象类型的传参

对于对象类型的参数,js采用的是按共享传递求值策略,即对于传入函数中的对象
参数,实际是传递对象的引用地址拷贝,函数的形参与实参指向的是相同的堆内存地址,
所以在函数中对形参对象的属性进行修改时会影响实参的值,如下所示:

1
var fn = function(object){
    object.property = 'modified';
};

var obj = {
    property:'origin'
};

console.log('before call:');
console.log(obj);
fn(obj);
console.log('after call:');
console.log(obj);

执行结果如下:
按共享传递
从上图中可以看出执行函数后,实参的对象属性值是被改变了的,即按共享传递的求值策略将会改变原先传入函数的对象参数的属性值。
注意上述只是修改了对象属性的值,如果我们给整个对象赋值会是什么样子的呢?看如下图所示:

1
var fn = function(object){
    object = 'modified';
    console.log('fn inner:');
    console.log(object);
};

var obj = {
    property1:'origin1',
    property2:'origin2'
};

console.log('before call:');
console.log(obj);
fn(obj);
console.log('after call:');
console.log(obj);

结果如下:
按共享传递-覆盖整个对象
从上图可以看出,给整个对象赋值调用函数前后并不会修改实际对象的值,这也就是按共享传递按引用传递求值策略的区别所在。

总结