<强>译者按:>强机智如你,应该可以答对文末的面试题吧?如果不能,请好好学习,天天编程:)
-
<李>
原文:解释值和引用在Javascript中
李> <李>译者:Fundebug李><强>为了保证可读性,本文采用意译而非直译。另外,本文版权归原作者所有,翻译仅用于学习。强>
JavaScript有5种基本的数据类型,分别是:布尔,null,定义,字符串和数字。这些基本类型在赋值的时候是通过值传递的方式。值得注意的是还有另外三种类型:数组,函数和对象,它们通过引用来传递。从底层技术上看,它们三都是对象。
基本数据类型
如果一个基本的数据类型绑定到某个变量,我们可以认为该变量包含这个基本数据类型的值。
<代码类=" language-js "> var x=10; var y=' abc '; var z=零;代码>
当我们使用<代码>=代码>将这些变量赋值到另外的变量,实际上是将对应的值拷贝了一份,然后赋值给新的变量。我们把它称作<代码>值传递> 代码。
<代码类=" language-js "> var x=10; var y=' abc '; var=x; var b=y; 控制台。日志(x, y, b)//10,“abc”, 10日,“abc”代码>
<代码> 代码>和<代码> x> 代码都包含10 b <代码> 代码>和<代码> y> 代码都包含<代码> ' abc '> 代码,并且它们是完全独立的拷贝,互不干涉。如果我们将<代码> 代码>的值改变,x <代码> 代码>不会受到影响。
<代码类=" language-js "> var x=10; var y=' abc '; var=x; var b=y;=5; b=癲ef”; 控制台。日志(x, y, a, b);//10,“abc”5“def”代码>
对象
如果一个变量绑定到一个非基本数据类型(数组、函数、对象),那么它只记录了一个内存地址,该地址存放了具体的数据。注意之前提到指向基本数据类型的变量相当于包含了数据,而现在指向非基本数据类型的变量本身是不包含数据的。
对象在内存中被创建,当我们声明<代码> arr=[]> 代码,我们在内存中创建了一个数arr组。<代码> 代码>记录的是该内存的地址。
<代码类=" language-js "> arr var=[];//(a) arr.push (1);//(b) 代码>
当执行完(a)之后,内存中创建了一个空的数组对象,其内存地址为<代码> # 001 代码>,<代码> 代码>指的arr向该地址。
变量 地址 对象 加勒比海盗 # 001 []当执行完(b)之后,数组对象中多了一个元素,但是数组的地址依然没有变,arr <代码> 代码>也没有变。
变量 地址 对象 加勒比海盗 # 001 [1]引用传递
对象是通过引用传递,而不是值传递,也就是说,变量赋值只会将地址传递过去。
<代码类=" language-js "> var参考=[1]; var refCopy=参考;代码>变量 地址 对象 参考 # 001 [1] refCopy # 001
<代码>引用代码>和<代码> refCopy> 代码指向同一个数组。如果我们更新<代码>引用代码>,<代码> refCopy> 代码也会受到影响。
<代码类=" language-js "> reference.push (2); 控制台。日志(参考,refCopy);//[1,2],[1,2]代码>变量 地址 对象 参考 # 001 [1,2] refCopy # 001
引用重新赋值
如果我们将一个已经赋值的变量重新赋值,那么它将包含新的数据或则引用地址。
<代码类=" language-js "> var obj={第一:' fundebug.com '}; obj={第二:' fundebug.cn '}; 代码>
<代码> obj> 代码从指向第一个对象变为指向第二个对象。
变量 地址 对象 obj # 001 {:' fundebug.com '} # 002 {二:' fundebug.cn '}如果一个对象没有被任何变量指向,就如第一个对象(地址为<代码> # 001> 代码),JavaScript引擎的垃圾回收机制会将该对象销毁并释放内存。