基本概念
截至到ES6,JavaScript 共有七种内置数据类型:
1、空值(null)
2、未定义(undefined)
3、布尔值( boolean)
4、数字(number)
5、字符串(string)
6、对象(object)
7、符号(symbol)
这里面除对象之外,其他统称为“基本类型”,基本类型用于表示简单的数据段。
对象,即“引用类型”,主要包括以下几种“子类型”:Object、Array、Data、RegExp、Function、Boolean、Number、String等,用于表示那些可能由多个值构成的复杂数据结构。
JavaScript 中的变量是没有类型的,只有值才有。变量可以随时持有任何类型的值。
基本类型和引用类型的区别
创建一个变量并为该变量赋值,当这个值保存到变量中以后,对于不同类型值可执行的操作则大相径庭:基本类型可以操作保存在变量中的实际的值;引用类型的值是保存在内存中的对象,JavaScript不允许直接操作对象的内存空间。在操作对象时,实际上是在操作对象的引用而不是实际的对象。具体区别可以分为下面几种情况:
1、添加属性
给基本类型的值添加属性没有任何意义,但也不会导致任何错误。
例子:
var name = "Tom";
name.age = 12;
alert(name.age);
//输出:undefined
可以为引用类型的值添加属性和方法,也可以改变和删除其属性和方法。
例子:
var person={};
person.age=12;
alert(person.age);
//输出:12
2、复制变量值
从一个变量向另一个变量复制基本类型的值时,实际上是创建一个新值,然后把该值复制给新变量,这两个变量可以参与任何操作而不会相互影响。
例子:
var str1="love";
var str2=str1;
str2=str2.slice(0,2)
alert(str1);
alert(str2);
//输出:love、lo
从一个变量向另一个变量复制引用类型的值时,实际上是为新变量添加一个指针,两个变量的指针指向堆中的同一个对象,改变其中一个变量,就会影响另一个变量。
例子:
var obj1={};
var obj2=obj1;
obj1.name="Tom";
alert(obj2.name);
//输出:Tom
3、传递参数
当向参数传递基本类型的值时,被传递的值会被复制给函数内部的局部变量(即函数的命名参数),因此这个局部变量的变化不会影响函数外部的值。
例子:
var num=1;
function addOne(n){
return n+1
}
var result=addOne(num);
alert(result);
alert(num);
//输出:2、1
当向参数传递引用类型的值时,会把这个值在内存中的地址复制给函数内部的局部变量,因此这个局部变量的变化会反映在函数的外部。
例子:
var person={};
function addName(obj){
obj.name="Tom";
}
addName(person);
alert(person.name);
//输出:Tom
值复制与值引用的相互转换
通过上面基本类型与引用类型的比较学习,可以得出这样的结论:基本类型值总是通过值复制的方式来赋值 / 传递;引用类型值则总是通过值引用的方式来赋值 / 传递;我们无法自行决定使用值复制还是值引用来赋值/传递,一切由值的类型来决定。
1、如果想通过值复制的方式来传递引用类型值,可以先为引用类型值创建一个复本,这样所有的操作就不会再影响原始值。
例子:
var nums = [1, 2, 3];
function addNum(arr) {
_nums = arr.slice(0); //创建复本
_nums.push(4);
return _nums.length;
}
alert(addNum(nums)); //输出:4
alert(nums.length); //输出:3
2、相反,如果要将基本类型值传递到函数内并进行更改,就需要将该值封装到一个引用类型值(对象、数组等)中,然后通过值引用的方式传递。
例子:
var obj = {
num: 1
};
function addOne(n) {
return obj.num += 1;
}
alert(addOne(obj)); //输出:2
alert(obj.num); //输出:2
文中的代码部分,带有“例子”和“测试代码”字样的,只是用来学习或测试某一功能用的代码,不可以直接用于项目的开发中。带有“代码如下”字样的,都是经过本人测试,简单修改即可用于项目开发中的代码,如有错误,欢迎指出。