@xudongh
2016-12-01T23:39:05.000000Z
字数 1616
阅读 1638
前端开发
ECMAScript包含两个不同类型的值:基本类型值和引用类型值。
当我们把变量赋值给一个变量时,解析器首先要做的就是确认这个值是基本类型值还是引用类型值。
基本数据类型就是简单的数据段,一共有五种,分别为Undifined、Null、Boolean、Number和String。
var a = 1;
var b = a;
b = 2;
console.log(a); //1
上面,b获取的值只是a值的一份拷贝,虽然,两个变量的值是相等,但是两个变量保存两不同的基本数据类型值。b只是保存了a复制的一个副本。所以,当b的值改变时,a的值依然是10。
var name = 'daniel';
name.toUpperCase(); // 'DANIEL'
console.log(name); // 'daniel'
var person = "lucy";
person.age = 18;
person.weight = 48;
console.log(person.age) // undefined
console.log(person.weight) //undefined
var a = 1;
var b = true;
console.log(a == b); //true
在比较两个不同类型的变量时js会进行一定的类型转换。上面的true先转换为数字1在与a比较,结果就是ture。
引用数据类型是保存在堆内存中的对象,JavaScript中不可以直接访问堆内存空间中的位置和操作堆内存空间,只能通过操作对象在栈内存。因此引用数据类型的数据,在栈内存中保存的实际上是对象在堆内存中的引用地址。通过这个引用地址可以快速查找到保存在堆内存中的对象。
var obj1 = new Object();
var obj2 = obj1;
obj2.name = "lucy";
console.log(obj1.name); // lucy
上面,我们声明了一个引用数据类型变量obj1,并把它赋值给了另外一个引用数据类型变量obj2。当我们obj2添加了一个name属性并赋值"lucy了"。obj1同样拥有了和obj2一样的name属性。说明这两个引用数据类型变量指向同一个堆内存对象,亦即相当于C语言中的指针。obj1赋值给obj2,实际只是把这个堆内存对象在栈内存的引用地址复制了一份给了obj2,但它们本质上共同指向了同一个堆内存对象。
//接上面的代码
obj2.name = "leon";
console.log(obj1.name); //leon
自然,给obj2添加name属性,实际上是给堆内存中的对象添加了name属性,obj2和obj1在栈内存中保存的只是堆内存对象的引用地址,虽然也是拷贝了一份,但指向的对象却是同一个。故而改变obj2引起了obj1的改变。
我们可以为引用类型添加属性和方法,也可以删除其属性和方法:
var person = {}; //创建个控对象 --引用类型
person.name = 'jozo';
person.age = 22;
person.sayName = function(){console.log(person.name);}
person.sayName(); // 'jozo'
delete person.name; //删除person对象的name属性
person.sayName(); // undefined
var person1 = {};
var person2 = {};
console.log(person1 == person2); // false
引用类型是按引用访问的,也就是说比较两个对象的堆内存中的地址是否相同,很明显,person1和person2在堆内存中地址是不同的: