类型
JavaScript 语言的每一个值都属于某一种数据类型。JavaScript 语言规定了 7 种语言类型。语言类型广泛用于变量、函数参数、表达式、函数返回值等场合。根据最新的语言标准,这 7 种语言类型是:
1. Undefined;
2.NULL
在JavaScript中,undefined
是一个全局变量,而非关键字,因此存在被覆盖的风险。为了避免这种情况,推荐使用void 0
来确保获得真正的undefined
值。null
则表示一个明确定义的空值,是一个安全的关键字,可以随时使用。因此,在编程中,应避免将变量赋值为undefined
,以区分未赋值和显式设为空的情况。
undefined 跟 null 有一定的表意差别,null 表示的是:"定义了但是为空值"。undefined 表示的是:"定义了但是未赋值"
3. Boolean;
有两个值, true 和 false, true 和 false是关键字
4. String;
JavaScript中字符串的最大长度为2^53 - 1,这并非指字符数,而是指UTF-16编码单元数。因此,实际字符数可能因编码长度而异。JavaScript 中的字符串是永远无法变更的,一旦字符串构造出来,无法用任何方式改变字符串的内容,所以字符串具有值类型的特征。
5. Number;
-
特殊值:
NaN
(Not a Number):表示一个未定义或不可表示的值。Infinity
:表示正无穷大。-Infinity
:表示负无穷大。+0
和-0
:JavaScript 中有两个零值,它们在算术运算中表现相同,但在除法中有所不同。
-
转换:
- JavaScript 提供了多种方法将值转换为数字,如
Number()
函数、一元加号(+
)和一元减号(-
)操作符。 - 字符串可以通过
parseInt()
和parseFloat()
函数转换为数字。
- JavaScript 提供了多种方法将值转换为数字,如
-
根据浮点数的定义,非整数的 Number 类型无法用 ==(=== 也不行) 来比较,这也是为什么在 JavaScript 中,0.1+0.2 不能 =0.3:
6. Symbol;
Symbol 是 ES6 中引入的新类型,它是一切非字符串的对象 key 的集合,在 ES6 规范中,整个对象系统被用 Symbol 重塑。
javascript
1.创建 Symbol 的方式是使用全局的 Symbol 函数。例如:
var mySymbol = Symbol("my symbol");
2.可以使用 Symbol.iterator 来自定义 for...of 在对象上的行为:
var o = new Object
o[Symbol.iterator] = function() {
var v = 0
return {
next: function() {
return { value: v++, done: v > 10 }
}
}
};
for(var v of o)
console.log(v); // 0 1 2 3 ... 9
给对象 o 添加了 Symbol.iterator 属性,并且按照迭代器的要求定义了一个 0 到 10 的迭代器,之后我们就可以在 for of 中愉快地使用这个 o 对象啦。
7. Object。
Object 是 JavaScript 中最复杂的类型,也是 JavaScript 的核心机制之一。Object 表示对象的意思,它是一切有形和无形物体的总称。
Number、String 和 Boolean,三个构造器是两用的,当跟 new 搭配时,它们产生对象,当直接调用时,它们表示强制类型转换。
Symbol 函数比较特殊,直接用 new 调用它会抛出错误,但它仍然是 Symbol 对象的构造器。
类型转换
因为 JS 是弱类型语言,所以类型转换发生非常频繁,大部分我们熟悉的运算都会先进行类型转换
JavaScript中的==
运算符因其复杂的跨类型比较规则而备受诟病,常被视为设计缺陷。建议避免使用==
,改用===
进行严格相等比较,以确保类型和值都相等。
装箱转化
- 基本类型(Number、String、Boolean、Symbol)可以转换为对应的对象。
- 通过函数的
call
方法或Object
函数可以实现装箱。
javascript
1.call方法
var symbolObject = (function(){ return this; }).call(Symbol("a"));
console.log(typeof symbolObject); //object
console.log(symbolObject instanceof Symbol); //true
console.log(symbolObject.constructor == Symbol); //true
2.使用内置的 Object 函数,我们可以在 JavaScript 代码中显式调用装箱能力。
var symbolObject = Object(Symbol("a"));
console.log(typeof symbolObject); //object
console.log(symbolObject instanceof Symbol); //true
console.log(symbolObject.constructor == Symbol); //true
- 装箱对象具有私有的
Class
属性,可通过Object.prototype.toString
获取。
javascript
var symbolObject = Object(Symbol("a"));
console.log(Object.prototype.toString.call(symbolObject)); //[object Symbol]
- 装箱频繁产生临时对象,应避免以优化性能。
拆箱转换
- 通过
ToPrimitive
函数,对象可转换为基本类型。 - 转换遵循"先拆箱再转换"的规则。
- 拆箱尝试调用
valueOf
和toString
获取基本类型,失败则抛出TypeError
。
javascript
var o = {
valueOf : () => {console.log("valueOf"); return {}},
toString : () => {console.log("toString"); return {}}
}
o * 2
// valueOf
// toString
// TypeError
- ES6引入
@@toPrimitive
Symbol,允许自定义拆箱行为。
javascript
var o = {
valueOf : () => {console.log("valueOf"); return {}},
toString : () => {console.log("toString"); return {}}
}
o[Symbol.toPrimitive] = () => {console.log("toPrimitive"); return "hello}
console.log(o + "")
// toPrimitive
// hello