You Don't Know JS
Value学习笔记
Array
var a = [ ];
a["13"] = 42;
a.length; // 14
应当注意到,在javascript中如果key只是一个数字字符串,将会被转化成十进制的key并且,会改变长度。
Array-like
在js中有两个常用到的类数组对象,一个是查找dom节点的结果对象,一个是函数的arguments属性。
将类数组对象转化为数组对象常见的有两种方式。
function foo() {
var arr = Array.prototype.slice.call( arguments )
arr.push( "bam" );
console.log( arr );
}
foo( "bar", "baz" ); // ["bar","baz","bam"]
通过es6新加属性Array.from进行转化:
var arr = Array.from( arguments )
strings
在javascript中数组是可变数据类型,而字符串是不可变数据类型。
var a = "foo";
var b = ["f","o","o"];
a[1] = "O";
b[1] = "O";
a; // "foo"
b; // ["f","O","o"]
//注意大小写不同。
字符串的不可变特性也导致了字符串的自有函数无法改变其自身,而是返回一个新的字符串
c = a.toUpperCase();
a === c; // false
a; // "foo"
c; // "FOO"
b.push( "!" );
b; // ["f","O","o","!"]
当然我们也可以借用Array的自有函数去处理字符串,只有不改变自身的Array函数才可以!!!!
a.join; // undefined
a.map; // undefined
var c = Array.prototype.join.call( a, "-" );
var d = Array.prototype.map.call( a, function(v){
return v.toUpperCase() + ".";
} ).join( "" );
c; // "f-o-o"
d; // "F.O.O."
尝试可改变自身Array.reverse方法去操作字符串:
Array.prototype.reverse.call( "strong" )
//Uncaught TypeError: Cannot assign to read only property '0' of object '[object String]'
将字符串反向输出的一个小方法:(注意这个方法不能改变unicode字符)
var c = a
// split `a` into an array of characters
.split( "" )
// reverse the array of characters
.reverse()
// join the array of characters back to a string
.join( "" );
c; // "oof"
Number
数字的语法
js只有一种数字类型:number,包括"整数"和小数形式。整数打引号是因为在js中,没有严格意义上的整数这也是一直以来js被人诟病的地方。
在js中的整数就是没有小数的十进制数。所以42.0及等同于整数42。
与大部分现代编程语言一样,js中的数字类型是基于IEEE 754标准来实现,该标准通常也被称为“浮点数”。js使用的是64位二进制。
var b = 42.
这种写法在js当中是可以的,但是为了可读性,并不建议这样写。
Number.prototype 中的toFixed()方法可指定小数部分的显示位数:
var a = 42.59
a.toFixed( 0 ); // "43"
a.toFixed( 1 ); // "42.6"
a.toFixed( 2 ); // "42.59"
a.toFixed( 3 ); // "42.590"
a.toFixed( 4 ); // "42.5900"
//多出位置用0补齐。
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"
较小的数值。
在大多数的编程语言当中,都面临下面的问题
0.1 + 0.2 === 0.3; // false
解决办法就是设立一个误差范围。称为“机器精度”。这个值通常是 2^-52 (2.220446049250313e-16)。
从 ES6 开始,该值定义在 Number.EPSILON 中
function numbersCloseEnoughToEqual(n1,n2) {
return Math.abs( n1 - n2 ) < Number.EPSILON;
}
检验整数
在es6当中,提供了Number.isInteger函数来进行检验。首先检验是否为整数格式,然后检验是否在js允许的范围内。
Number.isInteger( 42 ); // true
Number.isInteger( 42.000 ); // true
Number.isInteger( 42.3 ); // false
Number.isSafeInteger( Number.MAX_SAFE_INTEGER ); // true
Number.isSafeInteger( Math.pow( 2, 53 ) ); // false
Number.isSafeInteger( Math.pow( 2, 53 ) - 1 ); // true
32 位有符号整数
虽然整数最大能够达到 53 位,但是有些数字操作(如数位操作)只适用于 32 位数字,
所以这些操作中数字的安全范围就要小很多,变成从 Math.pow(-2,31)(-2147483648,
约-21 亿)到 Math.pow(2,31) - 1(2147483647,约 21 亿)。
a | 0 可以将变量 a 中的数值转换为 32 位有符号整数,因为数位运算符 | 只适用于 32 位
整数(它只关心 32 位以内的值,其他的数位将被忽略)。因此与 0 进行操作即可截取 a 中
的 32 位数位。
null和undefined
undefined指从未赋值。
null指曾赋过值,但是目前还没有。
null是一个特殊关键字,不是标识符,我们不能将其当做变量来使用或赋值。然而undefined却是一个标识符,可以被当作变量来使用或赋值。
function foo() {
undefined = 2; // 非常糟糕的做法!
}
foo();
function foo() {
"use strict";
undefined = 2; // TypeError!
}
foo();