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

原文: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)的方式遍历对象进行拷贝。

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

欢迎纰漏。

时间: 2024-08-11 12:28:32

JavaScript语法细节——引用与复制的相关文章

Javascript的赋值是引用or复制,及参数传递

  先来看2014年阿里巴巴前端线上笔试题:   var a = 1; var obj = {     b: 2 }; var fn = function () {}; fn.c = 3;   function test(x, y, z) {     x = 4;     y.b = 5;     z.c = 6;     return z; } test(a, obj, fn); alert(a + obj.b + fn.c); 答案是12,如果回答得正确,就没必要看下去.If not,就跟我

谈谈javascript语法里一些难点问题(一)

1)    引子 前不久我建立的技术群里一位MM问了一个这样的问题,她贴出的代码如下所示: var a = 1; function hehe() {          window.alert(a);          var a = 2;          window.alert(a); } hehe(); 执行结果如下所示: 第一个alert:   第二个alert:   这是一个令人诧异的结果,为什么第一个弹出框显示的是undefined,而不是1呢?这种疑惑的原理我描述如下: 一个页面

JavaScript语法树与代码转化实践

JavaScript 语法树与代码转化实践 归纳于笔者的现代 JavaScript 开发:语法基础与实践技巧系列文章中.本文引用的参考资料声明于 JavaScript 学习与实践资料索引中,特别需要声明是部分代码片引用自 Babel Handbook 开源手册;也欢迎关注前端每周清单系列获得一手资讯. JavaScript 语法树与代码转化 浏览器的兼容性问题一直是前端项目开发中的难点之一,往往客户端浏览器的升级无法与语法特性的迭代保持一致;因此我们需要使用大量的垫片(Polyfill),以保证

javascript 语法基础 想学习js的朋友可以看看_基础知识

1:javascript区分大小写 2:javascript每一条语句必须以";"结束,与C语言一样 3:输出:document.write("字符串")--->还可以输出对应的html标记 4:改变窗体的颜色document.bgColor="red"; 4:类型转换:parseInt,parseFloat 5:随机函数:parseInt(Math.random()*90+10) 产生10--100的随机数 5:弹出对话框:alert(&

《JavaScript DOM 编程艺术》读书笔记之JavaScript 语法_javascript技巧

注释         单行注释://         多行注释:/* */         "<!--"可以用作单行注释,由于和HTML的"<!--  -->"多行注释类似,容易混淆,所以不建议这种注释方法 变量        在JavaScript 语言里,变量和其他语法元素的名字都是区分字母大小写的.名字mood的变量与名字是Mood.MOOD或mOOd的变量没有任何关系,它们不是同一个变量.        JavaScript 语法不允许变量

IE和Firefox之间在JavaScript语法上的差异_javascript技巧

尽管 JavaScript 历史上使用冗长而令人生厌的代码块来标的特定浏览器的时期已经结束了,但是偶尔使用一些简单的代码块和对象检测来确保一些代码在用户机器上正常工作依然是必要的. 这篇文章中,我会略述一下 Internet Explorer 和 Firefox 在 JavaScript 语法上不同的 7 个方面. 1. CSS "float" 属性 获取给定对象的特定 CSS 属性的基本语法是 object.style 属性,而且有连字符的属性要用骆驼命名法来代替.例如,获取一个 I

12种不宜使用的Javascript语法

这几天,我在读<Javascript语言精粹>. 这本书很薄,100多页,正好假日里翻翻. 该书的作者是Douglas Crockford,他是目前世界上最精通Javascript的人之一,也是Json格式的创造者. 他认为Javascript有很多糟粕.因为1995年Brendan Eich设计这种语言的时候,只用了三个月,很多语言特性没有经过深思熟虑,就推向了市场.结果等到人们意识到这些问题的时候,已经有100万程序员在使用它了,不可能再大幅修改语言本身了.所以,Douglas Crock

python中引用与复制用法实例分析

  本文实例讲述了python中引用与复制用法.分享给大家供大家参考.具体分析如下: 在python中,任何不可变对象是传值的,而可变对象是传引用的. 不管是向函数传递参数或者是任何形式的对象复制来说,不可变对象(比如整数,字符串)被真正复制,而可变对象只是复制了一个对他们的引用,即在内存中只有一份对象,而引用两份. a=b 这样的赋值,就会创建对b的引用,对于象数字和字符串这样的不可变的对象,这种赋值实际是创建了b的一个副本 ? 1 2 3 4 5 6 7 8 9 10 11 >>>

JavaScript实现删除,移动和复制文件的方法_javascript技巧

本文实例讲述了JavaScript实现删除,移动和复制文件的方法.分享给大家供大家参考.具体如下: 这里利用JavaScript删除.移动和复制文件,运行前请确保文件已经存在,比如在C盘建立test.txt文件,然后在代码里修改为这个路径,再运行代码,就可以看到效果. <html> <head> <title>删除,移动和复制文件</title> </head> <body> <h2>删除,移动和复制文件</h2&g