码迷,mamicode.com
首页 > 编程语言 > 详细

变量-内存-作用域(JavaScript)

时间:2017-12-15 18:55:53      阅读:232      评论:0      收藏:0      [点我收藏+]

标签:javascrip   cti   efi   must   值传递   exp   影响   作用   hang   

基本类型和引用类型

ECMAScript变量可能包含两种不同数据类型的值:基本数据类型值和引用类型值。
基本数据类型为:Undefined,Null,Boolean,Number和String五种。
引用类型为:Object,Array,Date,RegExp,Function。

基本变量值复制

var a = 11;
var b = a;
console.log(b);//11
a = 22;
console.log(a);//22
console.log(b);//11 
//b still has not been changed after the a was changed

以上代码说明:值复制(b复制a的值)后的两个变量(a和b)可以参与任何操作而不会相互影响。

对象变量值复制

var obj1 = new Object();
var obj2 = obj1;
obj1.name = ‘MUSTANG‘;
console.log(obj2.name);//MUSTANG
obj1.age = 23;
obj2.age = 24;
console.log(obj1.age);//24

以上代码说明:obj2复制obj1后,两个对象指向的是同一个堆内存(即共享一个堆内存)。
因此任意一个对象(obj1或者obj2)添加/删除属性或者方法都是在堆内存中更改的(如果两个对象拥有同一个属性名或者方法名,则以最后一个为准,即同名时前者被后者覆盖)。

参数的传递

function add(num){
    num += 20;
    return num;
}
var a = 10;
var result = add(a);
console.log(result);//30
console.log(a);//10

以上代码说明:参数是按值传递的,如果num是按引用传递,那么a的值也将为30。因为引用传递是通过堆内存来传递的。

一个有趣的例子

//#1
function setName(obj){
    obj.name = ‘MUSTANG‘;
}
var horse = new Object();
setName(horse);
console.log(horse.name);//MUSTANG
//---------------------------------
//#2
function setName(obj){
    obj.name = ‘MUSTANG‘;
    obj = new Object();
    obj.name = ‘SHELBY‘;
}
var horse = new Object();
setName(horse);
console.log(horse.name);//MUSTANG
//still MUSTANG

以上代码说明:结合#1看#2,首先执行setName()时参数按值传递,但是此时的参数是一个对象,对象则是按引用传递。
因此当执行setName()时,obj对象(即person对象)添加了name属性。
前面讲到,对象添加/删除属性或者方法都是在堆内存中操作的,因此外部person也会添加name属性。
因此执行console.log(horse.name)得到的是’MUSTANG’而不是’SHELBY’
至于为什么obj = new Object(); obj.name = ‘SHELBY‘;不会生效是因为此时的obj是局部变量,而且此时的obj又是另外一个堆内存了,所以并不会影响外部结果。

文章说明:

参考资料文献:《JavaScript高级程序设计》(第3版) 第四章

水平有限,欢迎指正。

变量-内存-作用域(JavaScript)

标签:javascrip   cti   efi   must   值传递   exp   影响   作用   hang   

原文地址:http://www.cnblogs.com/wuzhi123/p/8044429.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!