vs传值接收页面怎么直接打开_传值vs传址

1、栈(stack)和堆(heap)

stack为自动分配的内存空间,它由系统自动释放;而heap则是动态分配的内存,大小不定也不会自动释放。

2、基本类型和引用类型

基本类型:存放在栈内存中的简单数据段,数据大小确定,内存空间大小可以分配。

5种基本数据类型有Undefined、Null、Boolean、Number 和 String,它们是直接按值存放的,所以可以直接访问。

引用类型:存放在堆内存中的对象,变量实际保存的是一个指针,这个指针指向另一个位置。每个空间大小不一样,要根据情况开进行特定的分配。

当我们需要访问引用类型(如对象,数组,函数等)的值时,首先从栈中获得该对象的地址指针,然后再从堆内存中取得所需的数据。

3、传值与传址

传值:实际复制的是值,存在两个不同的、独立的拷贝

传址:复制的只是对值的引用。如果通过这个新的引用修改了值,则这个改变对最初的引用来说也可见

let arr1=[1,2,3]

let arr3=arr2=arr1

arr2[0]=4

arr3=[5,6]

console.log(arr1,arr2,arr3) // [4, 2, 3] [4, 2, 3] [5, 6]let num4=arr1[0]

num4=7

console.log(arr1[0],num4) //4 7

4、传递参数

在《JavaScript高级程序设计》这本书中有这样一段话:有很多开发人员错误的认为:在局部作用域中修改的对象会在全局作用域中反映出来,就说明参数是按引用传递的。换句话说,尼古拉认为当一个对象是当做参数传递时,它是按值传递的。然后他举了个例子来证明这个结论:

function setName(obj) {

obj.name = "Nicholas";

obj = new Object();

obj.name = "Greg";

}

var person = new Object();

setName(person);

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

他解释到:如果person是按引用传递的,那么person就会自动被修改为指向其name属性值为"Greg"的新对象。但是,当接下来再访问person.name时,显示的值任然是"Nicholas"。这说明即使在函数内部修改了参数的值,但原始的引用任然保持不变。实际上,当在函数内部重写obj时,这个变量引用的就是一个局部对象了。而这个局部对象会在函数执行完毕后立即被销毁。

从上面的例子中,尼古拉得出的结论是:当一个对象当做参数传递时,它是按值传递的。

然而,我们可以肯定的是:当一个引用类型的对象不是当做参数传递时,它是按引用传递的。

我们来看另外一个例子:

var person = new Object();

var obj = person;

obj.name = "Nicholas";

obj = new Object();

obj.name = "Greg";

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

这个例子中person对象不是当做参数传递的,但person.name的值还是"Nicholas",这和person当做参数传递的情况是一样的。可以确定的是:这个例子中对象是按引用传递的。但按照尼古拉的说法这个例子中对象也是按值传递的。 那么可以得出结论:尼古拉的说法是错的。

我们可用图来说明一下这个问题。

当var person = new Object()时,可以用下面这幅图来描述变量和对象之间的关系:

当var obj = person时,可以用下面这幅图来描述它们之间的关系:

当obj = new Object()时,用下面的图描述它们的关系:

我们可以把Object当成一个中间人,它是联系person与obj的桥梁。之所以改变obj的属性值,会影响person其实是通过Object来传递的。当obj = new Object(),这时obj与Object之间的关系完全断开,与new Object建立了关系。当obj.name = "Greg",此时,obj与"Object"之间已没有关系,当然不会再影响"Object"。

书中的例子是一样的道理:

function setName(obj) {

obj.name = "Nicholas";

obj = new Object();

obj.name = "Greg";

}

var person = new Object();

setName(person);

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

obj相当于setName函数中的一个局部变量,把person传给函数就相当于var obj = person。其实我们完全可以把这个例子和上面介绍的那个例子看成是等价的,所以上面的图解也适用这个例子。

上面通过例子来说明尼古拉的结论是错的,从而得出自己的结论:ECMAScript中,对象无论是不是当成参数传递,都是按引用传递的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值