2019独角兽企业重金招聘Python工程师标准>>>

好像一般很少人讲到js中的引用和复制,不过弄清楚这个概念可以帮助理解很多东西

先讲一下很基础的东西,看看js中几种数据类型分别传的什么
引用:对象、数组、函数
复制:数字、布尔
字符串单独说明,因为它的特殊性,无法确定是传递引用还是复制数值(因为字符串的值是没法改变的,所以纠结这个问题也是没意义的)但是用于比较的时候显然是属于传值比较(稍后具体说比较的事)

下面讲一下在使用中的具体体现

最普通的使用就是赋值了
var a = 1;
var b = a;   //赋的是a的复制值
b ++;
alert(a);   //"1"   b的修改不影响a
/****************************************/
var a = [1];
var b = a;     //赋的是a的引用
b[0] ++;
alert(a);  //"2"   b的修改对a也有效    不过当然b = [2];这种修改对a是没用的。。。。。。

函数的参数
传值的传递:传给函数的是数值的一个复制,函数中对其的修改外部不可见
var a = 1;
var b = 2;
function change(a,b) {
  var c = a;
  a = b;      //用新引用覆盖
  b = c;
  alert(a);   //"2"        
  alert(b);   //"1"
}
change(a,b);
alert(a);   //"1"        
alert(b);   //"2"
传址的传递:传给函数的是数值的一个引用,函数中对其属性的修改外部可见,但用新引用覆盖其则在外部不可见,比如
var a = [1, 2, 3];
var b = [5, 6];
function change(a,b) {
  a[0] = 4;    //对其属性的修改外部可见 
  var c = a;
  a = b;      //用新引用覆盖
  b = c;
  alert(a);   //"5,6"        
  alert(b);   //"4,2,3"
}
change(a,b);
alert(a);    //"4,2,3"
alert(b);     //"5,6"
从结果可以看出a和b并没有互换   因为用新引用覆盖在外部不可见 这个很自然 因为函数只是拿到了引用 并没有权力更改引用

下面这个就不同了
var a = [1, 2, 3];
var b = [5, 6];
function change() {
  var c = a;
  a[0] = 4;
  a = b;
  b = c;
};
change();
alert(a);   //"5,6"
alert(b);   //"4,2,3"
这里成功实现互换 
又得提到js的块级作用域了,这个放某些语言里定然是要报未定义错误的,因为js没有块级作用域,所以它在change里找不到变量a,b就会自觉的到上层去找,所以这里的a,b是全局变量的引用
而上面的那个a,b则是change函数中的变量,在调用函数时传递了a,b的引用赋给了这两个变量,但是并不能改变全局中的a,b,这里换个名字大概就好理解多了
这个稍微提下    有些走题了。。。。
回到引用和复制 在比较运算中的注意事项
传值的比较比较的是数值 而传址的比较比较的是引用,引用不同即使数值相同也不等
1 == 1;    //true
1 === 1;   //true
[0] == [0]; //false
[0][0] == [0][0];    //true
[0][0] === [0][0];   //true
[0].toString() == [0].toString();   //true   
 
闭包中。。。。
闭包大概是js中最纠结的东西 我们部门面试的经典试题,常考不衰啊。。。。
这里我先不说闭包的东西,只说一下涉及传值和引用的部分,等我哪天确定自己可以用清晰的条例、简明的语言、生动的实例彻底的说清楚那个东西,再详细介绍这个提js不能不提的家伙。。。
闭包中,内部函数用外部函数的局部变量使用引用的方式而不是复制
其实这也是理解闭包的一个很重要的部分 可以用这个解释一个很经典的闭包现象,很多地方在说明闭包的时候都会用到的一个例子
/*构造一个函数,给数组中的节点设置事件处理程序,当点击一个节点时,alert出节点的序号*/
var add_handlers = function (nodes) {
    var i;
    for (i = 0, l = nodes.length; i < l; i ++) {
        nodes[i].onclick = function (e) {
           alert(i);    // 当然这里的结果必然是每次alert的都是节点总数。。。。
        }
    }
};
为什么每次alert的都是节点总数 而不是预期的序号呢,这个如果用复制和引用解释就相当容易了
因为内部函数在使用外部变量时使用引用的方式而不是复制,就是说我给每个节点设置onclick事件的时候将i的引用传递给了alert,当我点击节点触发onclick事件的时候,i的值已经变成了节点总数。。。
var add_handlers = function (nodes) {
    var i;
    for (i = 0, l = nodes.length; i < l; i ++) {
 
        nodes[i].onclick = function (i) {
           return function(){
           alert(i);   
           }
 }(i);
    }
};
这样修改后之所以正确是因为此时传进去的是i的值的复制,其实和普通函数是一样的,不要因为加了闭包就迷糊了,回归本源去思考就明白了,本源就是上面讲到的传址的传递
顺便提一句,不要被闭包这个古怪的名字唬住了,其实它和我们平时用的函数原理是一样的,抛开那些“更长的生命周期”“保护私有变量”等闭包所谓的特性,把它当成一个普通的函数(也可以换个角度把全局函数看成一个特殊的闭包),很容易就可以理解了
关键是要放下所有的浮华,回归最本质。。。。。。又跑题了。。。。。。

转载于:https://my.oschina.net/u/181793/blog/615955

js- 引用和复制(传值和传址)相关推荐

  1. php 函数传值_传址_函数参数,php函数的传值与传址(引用)详解

    在php中我们函数传值就比较简单了,但可能有些朋友地天真无邪函数传址或引用搞不明白,下面小编来给各位介绍在php中函数传值与传址(引用)介绍,希望对各位有所帮助. php中引用的用法: 1. 变量的引 ...

  2. php 函数传值_传址_函数参数,php函数的传值与传址(引用)详解_PHP教程

    在php中我们函数传值就比较简单了,但可能有些朋友地天真无邪函数传址或引用搞不明白,下面小编来给各位介绍在php中函数传值与传址(引用)介绍,希望对各位有所帮助. php中引用的用法: 1. 变量的引 ...

  3. Python 传值和传址 copy/deepcopy

    传值:被调函数局部变量改变不会影响主调函数局部变量 传址:被调函数局部变量改变会影响主调函数局部变量 Python参数传递方式:传递对象引用(传值和传址的混合方式),如果是数字,字符串,元组则传值:如 ...

  4. javascript . 05 json的组成、for...in 遍历对象、简单数据类型与复杂数据类型的传值与传址、内置对象...

    对象字面量  JSON var obj = { aaa :999}; var json={"aaa":999,"bbb":888}; "kay&quo ...

  5. 传值类型_java中的“传值”与“传址”问题

    "用对象来生成对象""对象作为参数进行传递""构造方法中的参数为对象"问题 本质上是"传值"与"传址" ...

  6. python函数传值还是地址_Python传值与传址

    1. 传值与传址的区别 传值就是传入一个参数的值,传址就是传入一个参数的地址,也就是内存的地址(相当于指针).他们的区别是如果函数里面对传入的参数重新赋值,函数外的全局变量是否相应改变:用传值传入的参 ...

  7. url 参数传递的两种方式_VB编程中的传值与传址两种参数传递方式,你清楚吗?...

    Tips:欢迎公众号设置为星标,VB技术干货文章可以第一时间看到.如您在学习VB过程中有独特的见解或者想法,欢迎投稿,可在公众号文章下直接留言. 推荐阅读 1. VB编程语言基础知识点总结 2. VB ...

  8. java函数返回多个值_深入理解被调函数与主调函数之间的传值、传址、值返回、址返回...

    函数的英文是function,有功能的意思,函数的作用在于合理分配功能,增强程序的可读性.合理分解功能,降低程序的复杂性.隐藏函数内部的数据和实现,尽可能将问题局限于函数本身. 函数可以理解为一种功能 ...

  9. Java系列之传值还是传址,你清楚了吗?

    前言 Java有两大数据类型:基本型和引用型.基本型有int(整型).short(短整型).长整型(long).byte(字节型).float(单精度型).double(双精度型).char(字符型) ...

  10. 【濡白的C语言】初学者-从零开始-5(模块化设计——函数,传值和传址)

    前言 C语言编程又称模块化设计,讲的就是对于一个程序而言,每一个功能都要类似于独立的实现,就像一个个板块,需要的时候拿出来即可.模块化的设计思想是一个程序员必不可缺少的思想. 如果有不明白的地方,或者 ...

最新文章

  1. haproxy配置文件
  2. 关于未能找到源文件“.NETFramework,Version=v4.0.AssemblyAttributes.cs”问题
  3. docker容器的本地局域网yum源优化
  4. Redux 并不慢,只是你使用姿势不对 —— 一份优化指南
  5. 【DevOps进行时】C/S端界面自动化测试:微软UIAutomation实践
  6. java中审核订单流程图_Java 后端横扫阿里、滴滴、美团总结的面试经验!
  7. Android控制EditText的焦点
  8. 利用SQL查找表中的质数(prime number)和完全数(perfect number)以及几个有趣的SQL语句...
  9. 2025年全球5G设备将达到14亿部 但4G仍占主导地位
  10. 基于Linux和MiniGUI的嵌入式系统软件开发指南(六)
  11. oracle 取表字段,oracle 取多级的表字段
  12. Himall商城LinqHelper帮助类(2)
  13. 我国计算机科学与技术发展历史,计算机科学与技术的发展趋势探析
  14. 支付宝转账银行卡/隐藏卡号
  15. python爬虫 破解js加密有道词典案列的两种方式以及思路总结
  16. 状态码(304 详解)
  17. 华为防火墙配置策略路由实现多个ISP出接口的智能选路
  18. 最新中国省市区县geoJSON格式地图数据Echarts地图数据
  19. scrapy实现二级页面爬取(以小说为例)
  20. msf之使用震网三代来提权

热门文章

  1. Spark初步 从wordcount开始
  2. 当代计算机技术在建筑设备中的应用,计算机技术在建筑设计中应用浅谈.doc
  3. c 语言转换成java语言,求助大神!!!JAVA转换成C语言
  4. 山东省大学计算机科学与技术,我校计算机科学与技术专业获山东省大学最佳专业排行榜第一名...
  5. 3.7 ExtJS RadioGroup(单选按钮组) 使用及注意事项
  6. JWT介绍以及java-jwt的使用
  7. data后缀文件解码_小白学PyTorch | 17 TFrec文件的创建与读取
  8. centos安装python3.6_Centos安装python3.6和pip步骤记录
  9. Abbott's Revenge UVA - 816 (输出bfs路径)
  10. #6281. 数列分块入门 5