读书笔记(一)——类型和值

141 阅读3分钟

void

setTimeout(...)函数返回一个数值(计时器间隔的唯一标识符,用于取消计时) void并不改变表达式的结果,只是让表达式不返回值

NaN

如果数学运算的操作数不是数字类型(或者无法解些为常规的十进制货十六禁制数字),就无法返回一个有效数字,这种情况下返回为NaN(not a number),无效的数值,坏数值

  var a = 2 / "foo";       // NaN
  typeof a === "number";   // true

NaN是一个“警戒值”(sentinel value,有特殊用途的常规值),用于指出数字类型中的错误情况,即“执行数学运算没有成功,这是失败后返回的结果”。 有人也许认为如果要检查变量的值是否为NaN,可以直接和NaN进行比较,就像比较null和undefined那样。实则不然。NaN是一个特殊值,它和自身不相等,是唯一一自反 (自反,reflexive,即 x === x 不成立)的值。而NaN != NaN 为true

  1. 怎么判断呢?使用isNaN
var a = 2 / "foo";
isNaN(a);                 // true

isNaN(..)有一个严重的缺陷,它的检查方式过于死板,就是“检查参数是否不是NaN,也不是数字”。但是这样做的结果并不太准确:

  var a = 2 / "foo";
  var b = "foo";
  a; // NaN
  b; "foo"

  window.isNaN( a ); // true
  window.isNaN( b ); // true——晕!
  1. 使用Number.isNan(...) ES6之前的polyfill
  if (! Number.isNaN) {
      Number.isNaN = function(n) {
        return (
            typeof n === "number" &&
            window.isNaN( n )
        );
      };
  }

  var a = 2 / "foo";
  var b = "foo";

  Number.isNaN( a ); // true
  Number.isNaN( b ); // false——好!

infinity -infinity 无穷数

Javascript使用有限数字表示法,所以运算结果有可能溢出,此时结果为infinity 或 -infinity infinity / infinity = NaN

0值

  1. 0 -0
var a = 0 / -3;

// 至少在某些浏览器的控制台中显示是正确的
a;                           // -0

// 但是规范定义的返回结果是这样!
a.toString();               // "0"
a + "";                     // "0"
String( a );                // "0"

// JSON也如此,很奇怪
JSON.stringify( a );   // "0"

特殊等式

Object.is()用来判断俩个值是否相等 ES6之前版本的polyfill

if(!Object.is) {
  Object.is = function(v1, v2) {
    // 判断是否是-0
    if (v1 === 0 && v2 === 0){
      return 1 / v1 === 1 / v2; //让它俩等于 infinity || -infinity
    }
    // 判断是否是NaN
    if (v1 !== v1){ // v1是否NaN
      return v2 !== v2
    }
    // 其他情况
    return v1 === v2;
    }
  }
}

值和引用

  1. 在JavaScript中变量不可能成为指向另一个变量的引用,JavaScript指向的是值 解释函数传参产生的疑惑
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],不是[4,5,6,7]

传递实参是,实际是将引用a的一个复本赋值给x,而a仍然指向[1, 2, 3]; 2. 标量基本类型值是不可更改的(字符串和布尔值也是如此)

function foo(x) {
  x = x + 1;
  x; // 3
})
var a = 2; 
var b = new Number( a ); // Object(a)也是一样
foo( b );
console.log( b ); // 是2,不是3

数值

  1. 二进制浮点数最大的问题,浮点数无法做到完全精确
0.1 + 0.2 === 0.3; // false

解决办法是设置一个误差范围值,即“机器精度”。对JavaScript来讲,一般是2^-52,定义在Number.EPSILON中。所以,可以使用Number.EPSILON来比较俩个数是否相等。

function numberCloseEnoughToEqual(n1, n2){
    return Math.abs( n1 - n2 ) < Number.EPSILON
}

数组

对数组声明后即可向其中加入值,不需要预先设定大小。使用delete运算符可以将单元从数组中删除,但是length不会变化。

  1. 在创建"稀疏"数组要注意:
var a = [ ];
a[0] = 1;
// 此处没有设置a[1]单元
a[2] = [ 3 ];
a[1];       // undefined
a.length;   // 3
  1. 数组通过数字进行索引,也可以包含字符串键值和属性(但这些并不计算在数组长度内)。如果字符串键值能够被强制类型转换为十进制数,则会被当做数字索引来处理。
  2. 将类数组转化成数组
  • slice
function foo() {
    var arr = Array.prototype.slice.call( arguments );
    arr.push( "bam" );
    console.log( arr );
}
foo( "bar", "baz" ); // ["bar", "baz", "bam"]
  • Array.from()
var arr = Array.from(arguments);