0. 前言
这篇文章是《你所不知道的JavaScript》读书笔记系列的第九篇文章。在这篇文章中,我想跟大家聊一聊JS中的原生函数。
- 《你所不知道的JavaScript》读书笔记(一):作用域和闭包(上)
- 《你所不知道的JavaScript》读书笔记(一):作用域和闭包(下)
- 《你所不知道的JavaScript》读书笔记(二):this指向问题
- 《你所不知道的JavaScript》读书笔记(三):对象和类(上)
- 《你所不知道的JavaScript》读书笔记(三):对象和类(下)
- 《你所不知道的JavaScript》读书笔记(四):类型与值
- 《你所不知道的JavaScript》读书笔记(五):强制类型转换
- 《你所不知道的JavaScript》读书笔记(六):语法
1. 内部属性[[class]]
- 所有
typeof返回值为"object"的对象都包含一个内部属性[[class]]。这个属性无法直接访问,一般通过Object.ptototype.toString()来查看 - 各个类型的
[[class]]属性:Object.prototype.toString.call([1,2,3])-> "[object Array]"Object.prototype.toString.call(/regex-literal/i)-> "[object RegExp]"Object.prototype.toString.call(null)-> "[object Null]"Object.prototype.toString.call(undifined)-> "[object Undefined]"Object.prototype.toString.call("abc")-> "[object String]"Object.prototype.toString.call(42)-> "[object Number]"Object.prototype.toString.call(true)-> "[object Boolean]"Object.prototype.toString.call(new Date())-> "[object Date]"
- 多数情况下,对象内部的
[[class]]属性和创建该对象的内建原生构造函数相对应 - 虽然
Null()和Undefined()这样的原生构造函数并不存在,但是内部的[[class]]属性值仍然是"Null"和"Undefined"
2. 封装与拆封
- 基本类型值没有
.length和.toString()这样的属性和方法,需要通过封装对象才能访问,此时JS会自动为基本类型值包装一个封装对象 - 对于
false的封装对象:
var a = new Boolean( false )
if(!a) {
// 执行不到这里
}
原因是为false封装了对象之后,他的类型值就变成了object,而我们对于object类型进行强制类型转换,得到的永远是true
- 一般不推荐直接使用封装对象
- 如果想要获得封装对象中的基本类型值,可以使用、
valueOf()函数
3. 原生函数作为构造函数
- 关于数组(array)、对象(object)、字符串(string)、函数(function)和正则表达式,通常喜欢以常量的形式创建
- 数组并没有预设长度这个概念,采用
new Array(length)创建出来的只是一个空数组,只不过它的length属性被设置成了执行的值 - 我们将包含至少一个“空单元”的数组称为稀疏数组
- 不同浏览器对于稀疏数组的开发控制台吓死你hi结果不同,例如:
var a = new Array(3)
var b = [undefined, undefined, undefined]
a在Chrome中显示为[ undefined x 3 ],这意味着他有三个值为undefined的单元,但实际上单元并不存在。b在Chrome中显示为[ undefined, undefined, undefined ].而在Firefox中,a显示为Array(3) [ <3 empty slots> ]
a.map()之所以执行失败,是因为数组中并不存在任何单元,join()首先假定数组不为空- 符号(Symbol)是具有唯一性的特殊值,用它来命名对象属性不宜导致重名
- 符号可以用作属性名,但无论是代码中还是开发控制台中都无法查看和访问它的值
- 我们可以使用
Symbol(..)原生构造函数来自定义符号。但它比较特殊,不能带new关键字,负责会出错 - 根据文档约定,可以将
String.prototype.XYZ简写为String#XYZ,对其他.prototype也同样如此