javascript的变量、传值、传址、参数之间关系


Posted in Javascript onJuly 26, 2015

先把收获晾一下:

1.javascrip变量包含两种类型的值,一种为引用类型的值,一种是基本类型的值。引用类型包括:Array,Object,Function(可以这么理解,非基本类型的都是引用类型);5种基本类型包括:undefined,null,string,boolean,number

2.函数的参数的传递的机制是复制变量值。

书上说:”把函数外部的值复制给函数内部的参数,就和把值从一个变量复制给另一个变量一样。基本类型的传递如同基本类型变量的复制一样,而引用类型的则如同引用类型变量的复制一样。“ 

”当一个变量复制引用类型的值时,同样也会将存储在变量对象中的值复制一份放到为新变量分配的空间中。不同的是这个值的副本实际上是一个指针,而这个指针指向存储在堆中的一个对象。复制操作结束后,两个变量实际上将引用同一个对象。因此改变其中一个变量,就会影响到另一个变量。“

【注意:复制引用类型的值,才是传址】

3.参数实际上是函数的局部变量。

----------------------------------------------------------------------------

基本概念的解释:

传值:把A的数值传到B,改变B,A不会跟着变,B存的是跟A一样的值;
传址:把A的地址传到B,改变B,A同时跟着变,B存的只是A的地址(类似电脑的快捷方式)。

一个具有值类型(value type)的数据存放在栈内的一个变量中。即是在栈中分配内存空间,直接存储所包含的值,其值就代表数据本身。值类型的数据具有较快的存取速度。

一个具有引用类型(reference type)的数据并不驻留在栈中,而是存储于堆中。即是在堆中分配内存空间,不直接存储所包含的值,而是指向所要存储的值,其值代表的是所指向的地址。当访问一个具有引用类型的数据时,需要到栈中检查变量的内容,该变量引用堆中的一个实际数据。引用类型的数据比值类型的数据具有更大的存储规模和较低的访问速度。

----------------------------------------------------------------------------

下面是三个问题。

【问题1】:为什么change(a)函数执行完之后,外面的a没有受干扰呢?

<script>
var a = [1, 2, 3];
function change(a) {
 console.log(a);//[1,2,3]
 a = 2;   //传值
 console.log(a);//2
}
change(a);
console.log(a);  //[1,2,3] 
</script>

问题1解答:因为change(a)的执行过程是这样的,首先将对象a(数组)传入到change以后,被复制给change的参数a。而后a=2是一个赋值语句,变成传值。此时a=2是值类型,并不涉及引用地址的问题。所以并没有影响外部的a。

【问题2】:为什么change(a)函数执行完之后,外面的a受到干扰呢?

<script>
 var a = [1, 2, 3];
 function change() { 
  a = 2;//传值
 }
 change();
 console.log(a);  //2 
</script>

 问题2解答:当执行change()的时候,函数在自己的执行环境中找寻作用域链,活动对象(activation object)并不包含变量a,于是沿着作用域链向上找,找到全局执行环境,发现变量a,于是此时函数内部的a和外部a在内存上是同一个地址,自然函数内部a变了,外部也会跟着变。

解析:问题2和问题1的区别在于,问题2并没有引入参数,所以不涉及复制变量的事情。

【问题3】:为什么change(a)函数执行完之后,外面的a受到干扰呢?

<script>
 var a = [1, 2, 3];
 function change(b) { 
  b[0] = 2;
 }
 change(a);
 console.log(a);  //[2,2,3]
</script>

问题3解答:这个和问题1非常类似,唯独不一样的就是a=2,换成了b[0]=2,我一开始也很疑惑,不说复制吗?参数b应该是个复制值,怎么会影响到外面的a呢?

的确,change函数执行时,参数b是a的复制值。因为a是引用类型,所以在函数内部是b和a按引用来访问的是一个地址的对象。b[0]=2的出现,并不影响在函数内部b和a引用的是同一个对象。

【问题4】:为什么change(a)函数执行完之后,外面的a没有受到干扰呢?

var a = [1, 2, 3];
 function change(b) { 
  console.log(b);//[1,2,3]
  b=2;
  b[0] = 2;
 }
 change(a);
 console.log(a);  //[1,2,3]

 问题4解答:change(b)执行过程是这样的,a对象传入change函数,将值和地址复制给b。b=2这句,此时b变成值类型了,并不涉及地址引用的问题,之后b[0]=2这句实际上毫无意义,因为此时b已经不是数组了,自然不具有b[0]这样的索引方式。所以b与a的地址引用关系其实在b=2之后就消失了。此时外界的a仍然是[1,2,3];

以上所述就是本文的全部内容了,希望大家能够喜欢。

Javascript 相关文章推荐
用Javascript实现UTF8编码转换成gb2312编码
Dec 22 Javascript
js 链式延迟执行DOME
Jan 04 Javascript
js AppendChild与insertBefore用法详细对比
Dec 16 Javascript
js监控IE火狐浏览器关闭、刷新、回退、前进事件
Jul 23 Javascript
解析javascript中鼠标滚轮事件
May 26 Javascript
javascript+ajax实现产品页面加载信息
Jul 09 Javascript
jquery实现漂亮的二级下拉菜单代码
Aug 26 Javascript
基于javascript实现随机颜色变化效果
Jan 14 Javascript
JS获取鼠标选中的文字
Aug 10 Javascript
JS实现简单的tab切换选项卡效果
Sep 21 Javascript
详解VUE-地区选择器(V-Distpicker)组件使用心得
May 07 Javascript
微信小程序获取公众号文章列表及显示文章的示例代码
Mar 10 Javascript
javascript实现动态导入js与css等静态资源文件的方法
Jul 25 #Javascript
javascript创建动态表单的方法
Jul 25 #Javascript
javascript文件加载管理简单实现方法
Jul 25 #Javascript
javascript页面倒计时实例
Jul 25 #Javascript
javascript解析xml实现省市县三级联动的方法
Jul 25 #Javascript
基于javascript实现单选及多选的向右和向左移动实例
Jul 25 #Javascript
javascript实现信息增删改查的方法
Jul 25 #Javascript
You might like
php中设置index.php文件为只读的方法
2013/02/06 PHP
jquery 学习之二 属性 文本与值(text,val)
2010/11/25 Javascript
firefox浏览器不支持innerText的解决方法
2013/08/07 Javascript
Javascript表格翻页效果实现思路及代码
2013/08/23 Javascript
Jquery实现侧边栏跟随滚动条固定(兼容IE6)
2014/04/02 Javascript
AngularJS上拉加载问题解决方法
2016/05/23 Javascript
javascript获取网页各种高宽及位置的方法总结
2016/07/27 Javascript
JS打印组合功能
2016/08/04 Javascript
基于JS实现发送短信验证码后的倒计时功能(无视页面刷新,页面关闭不进行倒计时功能)
2016/09/02 Javascript
Bootstrap table两种分页示例
2016/12/23 Javascript
vue.js实现单选框、复选框和下拉框示例
2017/07/18 Javascript
Angular 组件之间的交互的示例代码
2018/03/24 Javascript
node.js中ws模块创建服务端和客户端,网页WebSocket客户端
2019/03/06 Javascript
解决vue跨域axios异步通信问题
2019/04/17 Javascript
element表格翻页第2页从1开始编号(后端从0开始分页)
2019/12/10 Javascript
vue-quill-editor的使用及个性化定制操作
2020/08/04 Javascript
原生js实现自定义消息提示框
2020/11/19 Javascript
详解Python中的条件判断语句
2015/05/14 Python
浅谈Python中copy()方法的使用
2015/05/21 Python
Python实现的简单排列组合算法示例
2018/07/04 Python
Django 中间键和上下文处理器的使用
2019/03/17 Python
python编写简单端口扫描器
2019/09/04 Python
Python 转换RGB颜色值的示例代码
2019/10/13 Python
在django中自定义字段Field详解
2019/12/03 Python
Python 解决OPEN读文件报错 ,路径以及r的问题
2019/12/19 Python
python开发入门——set的使用
2020/09/03 Python
CSS3美化表单控件全集
2016/06/29 HTML / CSS
荷兰街头时尚之家:Funkie House
2019/03/18 全球购物
怎样声明接口
2014/09/19 面试题
旅游与酒店管理的自我评价分享
2013/11/03 职场文书
小学生美德少年事迹
2014/02/02 职场文书
倡议书格式模板
2014/05/13 职场文书
人事任命书怎么写
2014/06/05 职场文书
pytest配置文件pytest.ini的详细使用
2021/04/17 Python
MySQL 用 limit 为什么会影响性能
2021/09/15 MySQL
Jedis操作Redis实现模拟验证码发送功能
2021/09/25 Redis