JavaScript语法细节——引用与复制

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

我们都知道,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)的方式遍历对象进行拷贝。

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

欢迎纰漏。

目录
相关文章
|
2月前
|
JavaScript 前端开发
关于 JavaScript 代码里双重感叹号的语法
关于 JavaScript 代码里双重感叹号的语法
51 1
|
3月前
|
JavaScript 前端开发
JavaScript基础语法(类型转换)
JavaScript基础语法(类型转换)
28 0
|
3月前
|
JavaScript 前端开发 Java
JavaScript基础语法(流程控制语句)
JavaScript基础语法(流程控制语句)
25 0
|
24天前
|
JavaScript
为实例方法创建错误的引用(js的问题)
为实例方法创建错误的引用(js的问题)
11 0
|
24天前
|
JavaScript
为实例方法创建错误的引用(js的问题)
为实例方法创建错误的引用(js的问题)
|
1月前
|
JavaScript 前端开发 Web App开发
JavaScript基础语法(codewhy版本)(一)
JavaScript基础语法(codewhy版本)
90 1
JavaScript基础语法(codewhy版本)(一)
|
1月前
|
JavaScript 前端开发 网络架构
JavaScript的数组教程(最详细,更新至es6新语法)
JavaScript的数组教程(最详细,更新至es6新语法)
|
1月前
|
移动开发 前端开发 JavaScript
Java 和 JavaScript 的奇妙协同:语法结构的对比与探索(下)
Java 和 JavaScript 的奇妙协同:语法结构的对比与探索(下)
|
1月前
|
JavaScript 前端开发 Java
Java 和 JavaScript 的奇妙协同:语法结构的对比与探索(中)
Java 和 JavaScript 的奇妙协同:语法结构的对比与探索(中)
|
1月前
|
JavaScript 前端开发 Java
Java 和 JavaScript 的奇妙协同:语法结构的对比与探索(上)
Java 和 JavaScript 的奇妙协同:语法结构的对比与探索(上)