js中的传递参数

今天看到高程关于传递参数这一张的时候,说到,参数不管是基本类型还是引用类型的传递都是按值传递,但是

demo:

function setName(obj){
 obj.name=“Nicholas”;
 obj=new Object();
 obj.name=“Greg”;
}
 
var person=new Object();
setName(person);
alert(person.name)  //“Nicholas” 

书上说当函数内部重写obj时,这个变量引用的就是一个局部对象了,而这个局部对象会在函数执行完毕后立即被销毁(还是理解不了)

如果把obj=new Object();删掉,返回值为Greg;

于是重新看了内存的分配以及按值传递与按引用传递的区别,终于有了一点眉目

 

基本类型:存储在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量访问的位置

引用类型:存储在堆(heap)中的对象,也就是说,存储在变量处的值是一个指针(point,指向存储对象的内存地址。

 

 

 

ECMAScript中是不允许直接访问保存在堆内存中的对象的,所以在访问一个对象时,首先得到的是这个对象在堆内存中的地址,然后再按照这个地址去获得这个对象中的值,这就是按引用访问。而原始类型的值则是可以直接访问到的。

 

对于引用类型传参时的复制变量情况

在将一个保存着对象内存地址的变量复制给另一个变量时,会把这个内存地址赋值给新变量(因为这个引用值只能按引用访问得到),也就是说这两个变量都指向了堆内存中的同一个对象,他们中任何一个作出的改变都会反映在另一个身上。

 

 

 

 

进行传传参时:

 

基本类型只是把变量的值复制了一份给参数,之后参数和变量就互不影响了

 

而引用类型:对象变量里面的值是这个对象在堆内存中的内存地址,因此它传递的值也就是这个内存地址,这也就是为什么函数内部对这个参数的修改会体现在外部的原因了,因为它们都指向同一个对象。

 

 

用代码解释可能理解更形象:

注:代码范例来自JS高程P71

function setName(obj) {

    obj.name="Nicholas";

    obj=new Object( );

    obj.name="Greg";

}

var person=new Object( );

setName(person); 

 

//根据上述函数参数的特点,可以利用arguments对象来重写这个函数:

function setName( ) {

    arguments[0].name="Nicholas";

    arguments[0]=new Object( );

    arguments[0].name="Greg";

}

 

//将参数person传入setName函数,函数执行步骤入下:

function setName(person){

    arguments[0]=person; //arguments[0]person指向同一个对象

    arguments[0].name="Nicholas"; //也即person.name="Nicholas"

    arguments[0]=new Object; //重新定义arguments[0]。这时,arguments[0]已经跟 person“脱钩

    arguments[0].name="Greg"; //这行代码跟person已经没有关系了

}

 

//结果自然很明朗,没悬念

alert(person.name); // "Nicholas";

 

 

五、总结

  • ECMAScript中,所谓参数按值传递就是,将形式参数初始化为实际参数的值。或者说将所传递的实际参数的值复制到函数内部的arguments数组中。对于基本类型值,就是在函数内部创建了一个该值的副本;对于引用类型值则复制了一个指向某个对象的指针。所传递的参数依次对应于arguments数组中的arguments[0],arguments[1]等元素。
  • 而按引用传递,则相当于将形式参数初始化为实际参数本身。

注意:一个是只传递变量的值,一个是传递整个变量。这两者的内涵是完全不同的。

我们知道,ECMAScript中,每个变量都是一个用于保存值的占位符。如果参数是对像,则参数按值传递,意味着在函数内部,只能操作实际参数(对像)的属性和值,而不能操作实际参数(对像)本身。也就是说,你可以通过函数来改变函数外部所传入对像(参数)的属性和属性值;但你不能删除该变量,或改变此变量的引用对象。

 

对比两个例子巩固

var obj={
    attr:'obj attr value'
};
 
function func(o){
    o.attr="new attr value!";
}
 
func(obj);
 
console.log(obj.attr);   //new arr value
 
 
 
 
 
var obj={
    attr:'obj attr value'
};
 
function func(obj){
    obj={attr:'new attr value!'};   等价于obj=new Object( );
                             obj.arr=“new attr value”;
 
}
 
func(obj);
 
console.log(obj.attr);   //obj attr value' 

参考:http://www.jianshu.com/p/26ab38bdc176

 

 

原文地址:https://www.cnblogs.com/feilu2016/p/6927550.html