走进Javascript变量的世界
2016-09-25 13:55
155 查看
首先了解两个概念来引入本帖的重点讨论话题。
基本类型值
由五种基本数据类型(Number、Boolean、String、Null、Undefined)创建的值;
按值访问。可以操作保存在变量中实际的值。
如:
引用类型值
由复杂数据类型(Object)创建的值;
按引用访问。引用类型的值是保存在内存中的对象,操作对象变量实际上是操作对象的引用而不是对象本身。
下图可以帮助理解:
本帖讨论主题:
基本类型值和引用类型值的区别?
区别一:属性的动态赋值
对于引用类型值,可以为其添加属性和方法,也可以改变和删除其属性和方法。
如:
对于基本类型值,添加属性和方法会丢失属性
如:
区别二:赋值变量值
这个区别直接看例子讲解:
对于基本类型值。赋值给新变量后两个值是独立的,只是值的赋值。
对于引用类型值。赋值给新变量的是对象的引用,此时两个变量指向同一个对象。操作其中任何一个变量,也会影响另一个变量。
区别三:参数的传递
对于基本类型的值作为参数传递,同变量的值传递一样,只是值的传递,相互独立。
对于引用类型值的参数传递,引用类型的传递
区别四:检测类型
如:
instanceof 操作符介绍
如:
补充知识:
基本类型值
由五种基本数据类型(Number、Boolean、String、Null、Undefined)创建的值;
按值访问。可以操作保存在变量中实际的值。
如:
// 10是Number类型,属于基本类型值,将这个值赋值给变量a,直接操作a等于直接操作10这个值 var a = 10; alert(a + 10); // 返回结果 20
引用类型值
由复杂数据类型(Object)创建的值;
按引用访问。引用类型的值是保存在内存中的对象,操作对象变量实际上是操作对象的引用而不是对象本身。
下图可以帮助理解:
这里的Object类型指的是Object对象的引用,简单的说就是通过这个引用我可以在堆内存中找到Object这个对象。
本帖讨论主题:
基本类型值和引用类型值的区别?
区别一:属性的动态赋值
基本类型值和引用类型值的定义方法类似:创建一个变量并为该变量赋值。但是当这个值保存到变量中以后,对不同类型的值可以执行的操作则大相径庭。
对于引用类型值,可以为其添加属性和方法,也可以改变和删除其属性和方法。
如:
// 创建引用类型值并赋值给变量student,实际上赋值的是对象的引用 var student = new Object(); student.name = '小明'; alert(student.name); // 返回结果 "小明"
对于基本类型值,添加属性和方法会丢失属性
如:
// 创建基本类型值'小明'并赋值给变量name var name = '小明'; name.age = 12; alert(name.age); // 返回结果 undefined
区别二:赋值变量值
这个区别直接看例子讲解:
对于基本类型值。赋值给新变量后两个值是独立的,只是值的赋值。
var num1 = 12; // 把变量num1的值赋值给变量num2,二者只是值的赋复制,之后操作num2不会影响num1 var num2 = num1; num2 = num2 + 8; alert(num2); // 返回结果 20 alert(num1); // 返回结果 12
对于引用类型值。赋值给新变量的是对象的引用,此时两个变量指向同一个对象。操作其中任何一个变量,也会影响另一个变量。
var obj1 = new Object(); // 复制obj1的值给obj2,实际上复制的是对象的引用,二者仍然指向同一个对象,操作任何一个变量会影响另一个 var obj2 = obj1; obj2.name = 'bob'; alert(obj1.name); // 'bob' alert(obj2.name); // 'bob'
区别三:参数的传递
这里说的参数的传递是说方法里的参数,可以把参数变量当做是方法内部的一个局部变量看待。
对于基本类型的值作为参数传递,同变量的值传递一样,只是值的传递,相互独立。
// 定义方法,参数为基本类型值【参数变量为num】 function add (num) { num = num + 10; return num; } var num1 = 12; /* * 这里调用了add方法,将【全局变量num1】作为参数传递到了方法内部,可以看成是:将【全局变量num1】的值复制给了【参数变量为num】,只是值的复制,二者相互独立 */ alert(add(num1)); // 返回结果 20 alert(num1); // 返回结果 10 ,
对于引用类型值的参数传递,引用类型的传递
// 定义方法setName,参数为引用类型值 function setName (obj) { obj.name = 'bob'; } var obj1 = new Object(); // 这里调用setName方法,将变量obj1的对象引用传递给了方法。所以obj1和方法内的obj都指向了同一个对象,在方法内添加对象的属性,在外部的也同样改变 setName(obj1); alert(obj1.name); // 返回结果 'bob'
区别四:检测类型
首先对于所有的变量都可以使用 typeof 操作符得到数据类型。 检测基本类型值的类型时使用 typeof 操作符。 检测引用类型值的类型时使用 instanceof 操作符。
如:
var aa = 12; var bb = 'I am bob'; var cc = true; var dd; var ee = null; var ff = /^\w*$/; var gg = {key1: 'value1', key2: 'value2'}; var hh = function () { alert(111); } alert(typeof aa); // number alert(typeof bb); // string alert(typeof cc); // boolean alert(typeof dd); // undefined alert(typeof ee); // object alert(typeof ff); // object alert(typeof gg); // object alert(typeof hh); // function
这样写的话有个缺陷,就是对于基本数据类型可以直接得到我们想要的,但是对于复杂数据类型得到的结果都是Object,这不是我们想要的。我们想要知道的是这个变量到底是复杂数据类型中的哪一种,是数组还是正则表达式还是其它...
instanceof 操作符介绍
instanceof操作符可以帮助我们确定复杂数据类型的具体类型。
如:
var color = ['red', 'yellow']; // 数组 var reg = /^\w*$/; // 正则表达式 var obj = {}; alert(color instanceof Array); // true,是数组 alert(color instanceof Object); // true,因为数组是Object的子集 alert(reg instanceof RegExp); // true,是正则表达式 alert(reg instanceof Object); // true,因为正则表达式是Object的子集 alert(obj instanceof Object); // true,{} 和 new Object() 都能创建对象
var obj = { }; 等效于 var obj = new Object();二者都是创建对象,只是前者写法上更加简单。 复杂数据类型的子集有Array、Date、RegExp、Function等,具体用法见下篇帖子。
补充知识:
1.变量的生命周期。即一个变量什么时候会被创建出来,什么时候又会被销毁。知道了这个机制我们才能明确在一个具体步骤使用有意义的变量(即未被销毁的变量),减少错误的发生。 2.全局变量和局部变量的区别:使用 var 关键字定义的变量都是局部变量,其它为全局变量,全局变量容易变量名冲突造成错误,因此在定义变量时都使用 var 定义是个减少错误的好习惯。
相关文章推荐
- Java基础知识:走进Java的世界
- 带着大家走进iOS单元测试世界
- Web前端教程-01.走进前端工程师的世界
- 带你走进rsync的世界
- 传智播客成都Java培训,带你走进Java的世界...
- 走进Python世界(1)----第一个程序
- 走进Python世界(8)----使用dict和set
- 【眼前的苟且】2017英才计划“走进计算机世界”冬令营 游记
- 【走进Lua的世界之四】再进一步,获取lua表结构的数据
- 黑人透心凉,营销策划公司带您走进牙膏的世界
- 自己写的web标准教程,帮你走进web标准设计的世界——第三讲(html终结篇)
- 走进windows编程的世界-----windows进程
- 三猿开泰,走进普通、文艺、2B程序猿的逗比世界
- 走进Router世界
- 走进嵌入式 Linux 的世界
- ARKit-带你走进全新的世界(三:追踪/距离感应/AR尺子)
- 走进嵌入式Linux的世界
- 带你走进缓存世界(2):缓存入门
- 带你走进缓存世界(1):漫谈缓存
- 带你走进缓存世界(3):缓存原理