[译]基础中的基础,JavaScript中的值和引用

前几天忽然发现github上有一个大热门项目 —— “33 concepts every JavaScript developer should know”,目前已经将近25000个Stars。这个项目旨在帮助前端开发者掌握33个JavaScript基础概念。按作者话说,这些概念并不是开发所必需的,但它们是引导你通向前端大牛之路的基石。

遗憾的是,该项目中文版的文章收录不尽完整。所以本着学习与交流的目的,本人会把33个概念所涉及的文章利用业余时间竭尽所能的翻译出来,其中不免疏漏,望请指正。今天是第三篇,以下为正文:


基本类型引用类型,是我们作为前端开发所必需掌握的知识,不仅因为人们容易混淆其概念从而经常引起BUG,它还是面试中经常出现的一类问题。

我争取在这篇短文中,尽可能简单的阐述这个基础概念。


先别着急往下翻,你知道以下两个例子的结果吗?

示例1:

console.log([10] === [10]);
复制代码

示例2:

var oldArray = [];
var object = {};

object.newArray = oldArray;
oldArray.push(10);

console.log(object.newArray === oldArray);
复制代码

第一个结果是false,第二个结果是true。你答对了吗?我们来看看为什么会是这样。


在JavaScript中,我们以值的复制和值的引用来区分两种类型。他们是

基本类型(值的复制)

  • null
  • undefined
  • Number
  • String
  • Boolean
  • symbol

对象类型(值的引用)

扫描二维码关注公众号,回复: 5048595 查看本文章
  • Object
  • Array
  • Function

基本类型

var a = 5;
var b = a;
a = 10
console.log(a); // 10
console.log(b); // 5

// string, boolean, null, undefined同理
复制代码

我们把基本类型的值赋给变量,相当于把这个值复制一份,赋给另一个变量。

对象类型

注意哦,让人困惑的部分来了

var a = {};
var b = a;

a.a = 1;

console.log(a); // {a: 1}
console.log(b); // {a: 1}
复制代码

数组同理。

var a = [];
var b = a;

a.push(1);

console.log(a); // [1]
console.log(b); // [1]
console.log(a === b); // true
复制代码

当我们把对象类型赋给变量,相当于复制一个引用地址。该地址是声明变量时在内存中创建出来的。声明变量b时,仅仅是把这个地址的引用赋给它。所以我们更新该地址时,两个变量的值相同。

var a = [];     # Address #001 -> []                
                  # Variable a -> #001
                  
var b = a;     # Variable b -> #001

a.push(1);      # Address #001 -> [1]
复制代码
Variable Address Value
a #011 [1]
b #011 [1]

此时,我们再来看看“[10] === [10]”的例子

对比两个数组,全等操作符会检查它们是否指向同一个地址。所以,如果两个[10]不是同一个数组,结果为false。如果你想要对比两个数组或对象的值是否相同,倒是有一个简单但又限制颇多的方法。

JSON.stringify(a) === JSON.stringify(b)
复制代码

这样做的缺点是,对象或数组的属性顺序不同时会返回false。如果你想要更加健全的办法,可以选择lodash库中的isEqual()方法。


下一篇讲述隐式转型,敬请期待。

猜你喜欢

转载自juejin.im/post/5c4865bcf265da61193c26dc