运行时类型是代码实际运行过程中我们用到的类型。
类型
JavaScript语言的每一个值都属于某一种数据类型,JavaScript语言规定了7种语言类型,分别是:
Number
JavaScript 中的 Number 类型有 18437736874454810627(即 2^64-2^53+3) 个值。
JavaScript 中的 Number 类型基本符合 IEEE 754-2008 规定的双精度浮点数规则,但是 JavaScript 为了表达几个额外的语言场景(比如不让除以 0 出错,而引入了无穷大的概念),规定了几个例外情况:
- NaN,占用了 9007199254740990,这原本是符合 IEEE 规则的数字;
- Infinity,无穷大;
- Infinity,负无穷大。
String
String 用于表示文本数据。String 有最大长度是 2^53 - 1,这在一般开发中都是够用的,但是有趣的是,这个所谓最大长度,并不完全是你理解中的字符数。
字符串的最大长度,实际上是受字符串的编码长度影响的。Boolean
Boolean 类型有两个值,true
和false
,
表示逻辑意义上的真和假,有关键字true
和false
来表示两个值。Null
定义了,但是为空,是JavaScript关键词,可以使用null来获取null值。Undefined
表示未定义,他的类型只有一个值,就是undefined
。
任何变量再赋值前是Undefined
,值为undefined
。Symbol
Symbol 是 ES6 中引入的新类型,它是一切非字符串的对象 key 的集合,
在 ES6 规范中,整个对象系统被用 Symbol 重塑。
创建:var mySymbol = Symbol("my symbol");
Object
Object 是 JavaScript 中最复杂的类型,也是 JavaScript 的核心机制之一。Object 表示对象的意思,它是一切有形和无形物体的总称。对象分类
JavaScript 中的对象分类我们可以把对象分成几类。
宿主对象(host Objects)
由 JavaScript 宿主环境提供的对象,它们的行为完全由宿主环境决定。
内置对象(Built-in Objects)
由 JavaScript 语言提供的对象。
- 固有对象(Intrinsic Objects )
由标准规定,随着 JavaScript 运行时创建而自动创建的对象实例。
- 原生对象(Native Objects)
可以由用户通过 Array、RegExp 等内置构造器或者特殊语法创建的对象
普通对象(Ordinary Objects)
由{}语法、Object 构造器或者 class 关键字定义类创建的对象,它能够被原型继承。
问题及解答
- 为什么使用
void 0
代替 undefined?
这是 JavaScript 语言公认的设计失误之一。
在JavaScript
中,undefined
是一个变量,并非一个关键词,
避免无意中的篡改,建议使用void 0
代替undefined
。
- 0.1 + 0.2 不是等于 0.3 么?为什么 JavaScript 里不是这样的?
根据双精度浮点数的定义,Number 类型中有效的整数范围是 -0x1fffffffffffff
至 0x1ffffffffffff
f,
所以 Number 无法精确表示此范围外的整数。
- ES6 新加入的 Symbol 是个什么东西?
可以用字符串来描述,即使描述相同,Symbol也不相同,可以用来做对象的属性名。
他的创建不需要使用 new关键词。直接 var mySymbol = Symbol("my symbol")
- 为什么给对象添加的方法能用在基本类型上?
基本类型的构造函数,
Number,String,Boolean,Symbol,直接使用可以用来做强制类型转换,
使用new 来创建该数据类型(除了Symbol,直接Symbol(‘symbol’))
可以在构造器的原型上添加属性或者方法,那在基本类型上就可以访问了。
如下代码:
Number.prototype.say = function () {console.log(this)}
let num = 100
num.say()
Number(100)
类型转换
因为 JS 是弱类型语言,所以类型转换发生非常频繁,大部分我们熟悉的运算都会先进行类型转换。
StringToNumber
NumberToString
装箱装换
在 JavaScript 中,没有任何方法可以更改私有的 Class 属性,因此 Object.prototype.toString 是可以准确识别对象对应的基本类型的方法,它比 instanceof 更加准确。但需要注意的是,call 本身会产生装箱操作,所以需要配合 typeof 来区分基本类型还是对象类型。
拆箱转换
new的原理,创建一个空对象,去扩展它的属性和方法,并将构造函数当中的this指向新创建的对象。
并且对该对象的proto进行赋值,自身构造函数的原型。