博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JavaScript语法细节——引用与复制
阅读量:7089 次
发布时间:2019-06-28

本文共 1766 字,大约阅读时间需要 5 分钟。

原文:

我们都知道,JS中变量的赋值有两种方式,最近在折腾自己写的,碰到了很多平时没注意的问题。正好,那边处理清楚了,稍微整理一下关于引用与复制相关知识,可能会不定期增加新碰到的问题,有错误希望看到的人指出,避免传播不正确的知识。

先大致分一下类,引用类型:Object以及其旗下的Array,Date,RegExp,Function;基本包装类型:Boolean,number,String。

在赋值与传递参数的时候,引用类型传递的是指针,基本包装类型是复制新值传递。常见的情况我就不啰嗦了,一下主要是一些碰到过的容易理解出错的情况,以及探究后得出的个人结论。

修改指针变量不一定会影响到引用对象

可能一下不太好理解这个,来点简单暴力的demo就好说明问题了。

var    arr1 = [1, 2, 3],    arr2 = arr1; arr2 = [4, 5, 6]; console.log(arr1);console.log(arr2);

这个demo比较简单,结果是:arr1为[1, 2, 3]  arr2为[4, 5, 6]

为什么修改arr2后arr1没有改变,arr2 = [4, 5, 6]修改的是arr2这个指针变量的指向,并没有碰到原引用的数组。

下面这种情况则会修改到原对象。

var    arr1 = [1, 2, 3],    arr2 = arr1; arr2.pop(); console.log(arr1);console.log(arr2);

此时的结果为: arr1 arr2都等于[1, 2],arr2.pop()相当于执行[1, 2, 3].pop(),因此arr2引用的原匿名对象被修改了。

因此在操作引用类型的时候,要注意是否修改的是原对象。来一个稍微啰嗦有点的demo:

var    arr1 = [1, 2, 3],    arr2 = arr1;function test (a) {    console.log(a);    a = [4, 5, 6];    console.log(a);}test(arr2);console.log(arr1);console.log(arr2);

上面的输出结果根据之前的测试应该是

var    arr1 = [1, 2, 3],    arr2 = arr1;function test (a) {    console.log(a); // [1, 2, 3]    a = [4, 5, 6];    console.log(a); // [4, 5, 6]}test(arr2);console.log(arr1); // [1, 2, 3]console.log(arr2); // [1, 2 ,3]

因为在传递arr2给test的时候,相当于执行了a = arr2因此情况跟第一个demo一样了。同理,将a=[4, 5, 6]改为a.pop(),那么结果如同第二个demo。

来一个函数自己修改自己的demo:

var test = function () {    var a = 1;    test = function () {        var b = 3;    }};test();console.log(test);

此时的test内部为var b = 3;这种方法有个高大上叫法叫惰性载入,具体我就不啰嗦了,可以百度一下或者谷歌两下。利用的就是函数本身也是引用类型的特点。

下面的这个demo是引用类型中引用类型:

var obj1 = {        arr: [1, 2, 3]    },    obj2 = obj1;obj2.arr = [4, 5, 6];console.log(obj1);

输出结果中,obj1被修改了,不难理解执行obj2.arr = [4, 5, 6]时,相当于执行obj1.arr = [4, 5, 6],直接修改了原对象。因此采用简单的赋值操作得不到一个对象的拷贝。取得拷贝的话可以用for(key in object)的方式遍历对象进行拷贝。

至于原始类型字符串数字之类的基本类型就不多写了,那些都是复制操作,获得的是一个新值。

欢迎纰漏。

转载地址:http://qvfql.baihongyu.com/

你可能感兴趣的文章
C# IEnumerable和IEnumerator的区别,如何实现
查看>>
android adb命令行工具使用
查看>>
[转]聊聊.net程序设计——浅谈使用VS2010建模拓展
查看>>
Central Europe Regional Contest 2011
查看>>
每天一个linux命令(12):more命令
查看>>
javascript 正则替换字符的新方法!
查看>>
OSGI:从面向接口编程来理解OSGI
查看>>
前端之JavaScript(1) - 浅谈JavaScript函数与栈
查看>>
WayOs 帐号到期自动清理工具,致浪费在清理到期用户的青春
查看>>
新买的mac笔记本,发现vi编辑器没有颜色的解决方案
查看>>
object-c 混编 调用C,C++接口
查看>>
JQuery Ajax实例总结
查看>>
CentOS中文件夹基本操作命令
查看>>
VS2008 Project : error PRJ0019: 某个工具从以下位置返回了错误代码: "正在执行生成后事件..."解决方案...
查看>>
js判断图片是否存在,并做处理
查看>>
触摸屏
查看>>
webservice 测试窗体只能用于来自本地计算机的请求
查看>>
Java 中队列的使用
查看>>
再见 2014,你好 2015
查看>>
13 SELECT 以外的内容
查看>>