We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
需要注意,空白单元可能会导致出人意料的结果,和将数组元素显式赋值为 undefined 是有所区别的(在不同浏览器上表现也不一致)
undefined
var a = [] a[0] = 1 a[2] = 3 a[1] // undefined a.length // 3
由于数组也是对象,所以也可以包含字符串键,但是不会被计算在数组长度内。如果字符串键能被强制类型转换为十进制数字的话,它会被当做数字键处理
var a = [] a[0] = 1 a['foo'] = 'bar' a.length // 1 a['foo'] // bar a.foo // bar a['1'] = 3 a.length // 2 a[1] // 3
一些DOM查询操作,或是 arguments 对象得到的都是类数组,可以将他们转化为真正的数组。
arguments
function foo(a, b) { var arr = Array.prototype.slice.call(arguments) // ES6: var arr = Array.from(arguments) arr.push('bam') console.log(arr) } foo('bar', 'baz') // ['bar', 'baz', 'bam']
javascript中字符串是不可变更的,即字符串的成员函数不会改变其原始值,而总是创建并返回一个新的字符串。同时字符串也是类数组,可以借用数组的非变更方法来处理字符串
var str = 'abc' var arr = Array.prototype.slice.call(str) arr // ['a', 'b', 'c'] var newStr = Array.prototype.join.call(str, '-') newStr // 'a-b-c'
如果借用数组的变更方法来处理字符串(和书中结论不一致,推测是最新浏览器js引擎对字符串对象的键 setter 做了限制)
setter
var str = Array.prototype.reverse.call('abc') // Uncaught TypeError: Cannot assign to read only property '0' of object '[object String]'
javascript只有一种数值类型:number,没有真正意义上的整数。javascript中的整数即没有小数的十进制数,所以 42.0 === 42。
42.0 === 42
特别大和特别小的的数字默认用指数格式显示,与 toExponential() 函数输出的结果相同。
toExponential()
var a = 5e10 a // 50000000000 a.toExponential() // '5e+10'
toFixed() 方法可以指定小数部分的显示位数,但是需要注意,返回的是给定数字处理后的字符串
toFixed()
var a = 42.59 a.toFixed(0) // '42' a.toFixed(1) // '42.6' a.toFixed(2) // '42.59' a.toFixed(3) // '42.590' a.toFixed(4) // '42.5900'
toPrecision() 方法用来指定有效数位的显示位数,同样返回的是字符串
toPrecision()
var a = 42.59 a.toPrecision(1) // '4e+1' a.toPrecision(2) // '43' a.toPrecision(3) // '42.6' a.toPrecision(4) // '42.59' a.toPrecision(5) // '42.590' a.toPrecision(6) // '42.5900'
数字字面量也可以使用相应的方法(运算时字面量会被Number对象封装),但是需要注意 . 运算符,因为它是一个有效的数字字符
.
42.toFixed(3) // SyntaxError (42).toFixed(3) // '42.000' 0.42.toFixed(3) // '0.420' 42..toFixed(3) // '42.000' 42 .toFixed(3) // '42.000'
数字字面量同样可以表示二进制、八进制、十六进制,推荐表示进制的字符统一采用小写
0xf3 // 243 十六进制 0o363 // 243 八进制 0b11110011 // 243 二进制 0363 // 243 八进制,但是严格模式下已经不支持,不建议使用
二进制浮点数(IEEE 754规范)最大的问题是,小数并不精确
0.1 + 0.2 === 0.3 // false
可以通过设置一个误差值的方式来处理小数,通常称为机器精度(machine epsilon)。在javascript中,这个值是 2^-52(2.220446049250313e-16) ,在ES6中,这个值被定义在 Number.EPSILON 中。
2^-52(2.220446049250313e-16)
Number.EPSILON
if(!Number.EPSILON) { Number.EPSILON = Math.pow(2, -52) } function numberEqual(n1, n2) { return Math.abs(n1 - n2) < Number.EPSILON } numberEqual(0.1 + 0.2, 0.3) // true
能够呈现的最大浮点数大约是 1.798e+308 ,它定义在 Number.MAX_VALUE 中。最小浮点数大约是 5e-324 ,它定义在 Number.MIN_VALUE 中。能够被安全呈现的最大整数是 2^53 - 1 ,在ES6中,被定义在 Number.MAX_SAFE_INTEGER ,同理最小整数是 Number.MIN_SAFE_INTEGER 。可以通过 Number.isInteger 和 Number.isSafeInteger 来检测一个数是否是整数/安全整数。
1.798e+308
Number.MAX_VALUE
5e-324
Number.MIN_VALUE
2^53 - 1
Number.MAX_SAFE_INTEGER
Number.MIN_SAFE_INTEGER
Number.isInteger
Number.isSafeInteger
需要注意的是,有些数字操作(如数位操作)只适用于32位数字,此时数字的安全范围为 Math.pow(-2, 31) 到 Math.pow(2, 31) - 1
Math.pow(-2, 31) 到 Math.pow(2, 31) - 1
在非严格模式下,可以为全局标识符 undefined 赋值(千万不要这么做!)
function foo() { undefined = 2 } function bar() { 'use strict' undefined = 2 // TypeError }
运算符 void 并不改变表达式的结果,只是让表达式不返回值
void
var a = 42 console.log(void a, a) // undefined 42
void 使用场景:
function doSomething() { if(!APP.ready) { return void setTimeout(doSomething, 100) // 和下方注释代码等价 // setTimeout(doSomething, 100) // return } // 返回处理完成后的结果 var result return result } if(doSomething()) { // 继续做其他事情 }
NaN(not a number) 是唯一一个非自反的值,即 NaN !== NaN 。检查一个数值是否是 NaN 有两种方式,其中全局 isNaN 函数有个严重的缺陷,应该使用ES6提供的 Number.isNaN ,或者通过唯一一个非自反的值这个特性来判断
NaN(not a number)
NaN !== NaN
NaN
isNaN
Number.isNaN
var a = 2 / 'foo' var b = 'bar' window.isNaN(a) // true window.isNaN(b) // true Number.isNaN(a) // true Number.isNaN(b) // false
在JavaScript中,存在无穷数 Infinity(Number.POSITIVE_INFINITY) 和 -Infinity(Number.NEGATIVE_INFINITY) ,当运算结果溢出时,会在无穷数和最大数之间做一个“就近取整”。同时 Infinity / Infinity 是一个未定义操作,结果为 NaN
Infinity(Number.POSITIVE_INFINITY) 和 -Infinity(Number.NEGATIVE_INFINITY)
Infinity / Infinity
var a = Number.MAX_VALUE // 1.7976931348623157e+308 a + Math.pow(2, 970) // Infinity (距离Infinity更近) a + Math.pow(2, 969) // 1.7976931348623157e+308 (距离Number.MAX_VALUE更近)
0 在JavaScript中是区分正负的。这在某些场景下是必要的,例如“动画帧的移动速度”,数字的符号位可以用来记录移动方向,假设某个时刻速度值为 0 ,那么保留正负号不会丢失移动方向。
0
var a = 0 / -3 // -0 var b = 0 // 0 a.toString() // '0' a + '' // '0' String(a) // '0' JSON.stringify(a) // '0' // 有意思的是,反向操作是正确的 + '-0' // -0 Number('-0') // -0 JSON.parse('-0') // -0 // 比较操作 a == b // true a === b // true b > a // false // 区分0和-0 function isNegZero(n) { return (n === 0) && (1 / n === -Infinity) } isNegZero(a) // true isNegZero(b) // false
ES6中,可以通过 Object.is() 来判断两个值是否绝对相等,可以借用这个方法来判断特殊数值(性能比运算符差)
Object.is()
var a = 2 / 'foo' var b = 0 / -1 Object.is(a, NaN) // true Object.is(b, -0) // true
JavaScript中没有指针,变量不可能成为另一个变量的引用,引用指向的是某一个具体的值。赋值和引用完全根据值的类型来决定:null, undefined, string, number, boolean, symbol 总是通过值复制的方式赋值/传递,object(以及其各种子类型 function, array, regexp) 总是通过引用复制的方式来赋值/传递。
null, undefined, string, number, boolean, symbol
object(以及其各种子类型 function, array, regexp)
由于引用指向的是值而非变量,所以一个引用无法更改另一个引用的指向
var a = [1] var b = a a // [1] b // [1] b = [2] a // [1] b // [2]
对于函数参数也是同理
function foo(x) { x.push(4) x // [1, 2, 3, 4] x = [4, 5, 6] x.push(7) x // [4, 5, 6, 7] } var a = [1, 2, 3] foo(a) a // [1, 2, 3, 4]
需要注意的是,因为基本类型值是不可更改的,所以对应对象子类型在引用时,如果遇到值发生变化的情景,会解除引用并将变化的值转化为基本类型(而非基本类型对应的对象子类型)
var a = new Number(1) b = a a // Number{1} b // Number{1} typeof a // 'object' b = b + 1 b // 2 a // Number{1} typeof b // 'number'
The text was updated successfully, but these errors were encountered:
No branches or pull requests
数组
需要注意,空白单元可能会导致出人意料的结果,和将数组元素显式赋值为
undefined
是有所区别的(在不同浏览器上表现也不一致)由于数组也是对象,所以也可以包含字符串键,但是不会被计算在数组长度内。如果字符串键能被强制类型转换为十进制数字的话,它会被当做数字键处理
一些DOM查询操作,或是
arguments
对象得到的都是类数组,可以将他们转化为真正的数组。字符串
javascript中字符串是不可变更的,即字符串的成员函数不会改变其原始值,而总是创建并返回一个新的字符串。同时字符串也是类数组,可以借用数组的非变更方法来处理字符串
如果借用数组的变更方法来处理字符串(和书中结论不一致,推测是最新浏览器js引擎对字符串对象的键
setter
做了限制)数字
javascript只有一种数值类型:number,没有真正意义上的整数。javascript中的整数即没有小数的十进制数,所以
42.0 === 42
。特别大和特别小的的数字默认用指数格式显示,与
toExponential()
函数输出的结果相同。toFixed()
方法可以指定小数部分的显示位数,但是需要注意,返回的是给定数字处理后的字符串toPrecision()
方法用来指定有效数位的显示位数,同样返回的是字符串数字字面量也可以使用相应的方法(运算时字面量会被Number对象封装),但是需要注意
.
运算符,因为它是一个有效的数字字符数字字面量同样可以表示二进制、八进制、十六进制,推荐表示进制的字符统一采用小写
二进制浮点数(IEEE 754规范)最大的问题是,小数并不精确
可以通过设置一个误差值的方式来处理小数,通常称为机器精度(machine epsilon)。在javascript中,这个值是
2^-52(2.220446049250313e-16)
,在ES6中,这个值被定义在Number.EPSILON
中。能够呈现的最大浮点数大约是
1.798e+308
,它定义在Number.MAX_VALUE
中。最小浮点数大约是5e-324
,它定义在Number.MIN_VALUE
中。能够被安全呈现的最大整数是2^53 - 1
,在ES6中,被定义在Number.MAX_SAFE_INTEGER
,同理最小整数是Number.MIN_SAFE_INTEGER
。可以通过Number.isInteger
和Number.isSafeInteger
来检测一个数是否是整数/安全整数。需要注意的是,有些数字操作(如数位操作)只适用于32位数字,此时数字的安全范围为
Math.pow(-2, 31) 到 Math.pow(2, 31) - 1
特殊数值
在非严格模式下,可以为全局标识符
undefined
赋值(千万不要这么做!)运算符
void
并不改变表达式的结果,只是让表达式不返回值void
使用场景:NaN(not a number)
是唯一一个非自反的值,即NaN !== NaN
。检查一个数值是否是NaN
有两种方式,其中全局isNaN
函数有个严重的缺陷,应该使用ES6提供的Number.isNaN
,或者通过唯一一个非自反的值这个特性来判断在JavaScript中,存在无穷数
Infinity(Number.POSITIVE_INFINITY) 和 -Infinity(Number.NEGATIVE_INFINITY)
,当运算结果溢出时,会在无穷数和最大数之间做一个“就近取整”。同时Infinity / Infinity
是一个未定义操作,结果为NaN
0
在JavaScript中是区分正负的。这在某些场景下是必要的,例如“动画帧的移动速度”,数字的符号位可以用来记录移动方向,假设某个时刻速度值为0
,那么保留正负号不会丢失移动方向。ES6中,可以通过
Object.is()
来判断两个值是否绝对相等,可以借用这个方法来判断特殊数值(性能比运算符差)值和引用
JavaScript中没有指针,变量不可能成为另一个变量的引用,引用指向的是某一个具体的值。赋值和引用完全根据值的类型来决定:
null, undefined, string, number, boolean, symbol
总是通过值复制的方式赋值/传递,object(以及其各种子类型 function, array, regexp)
总是通过引用复制的方式来赋值/传递。由于引用指向的是值而非变量,所以一个引用无法更改另一个引用的指向
对于函数参数也是同理
需要注意的是,因为基本类型值是不可更改的,所以对应对象子类型在引用时,如果遇到值发生变化的情景,会解除引用并将变化的值转化为基本类型(而非基本类型对应的对象子类型)
The text was updated successfully, but these errors were encountered: