看完这篇文章,你将了解:

  • Date 对象 now 方法和 getTime() 方法的区别
  • Math.round 对负数的特殊处理机制
  • 理解 var a = b = 1
  • 变量提升的一个陷阱

一. Date.now vs (new Date).getTime()

首先,它们功能都是返回当前时间的数字形式

然后,区别在于:now 是构造函数才有的方法,getTime 是实例对象才有的方法

let t = new Date()
t.getTime() // 正确
t.now()  // 错误

Date.now() // 正确
Date.getTime() // 错误

二. Math.round 对负数的四舍五入

JS 中该方法对负数的处理与其他语言不同

Math.round(11.5) // 12
Math.round(-11.5) // -11
Math.round(-11.6) // -12
Math.round(-11.51) // -12

可以看出,正数的四舍五入正常,负数的四舍五入有一个反常识的地方

如果负数的小数位刚好等于 0.50,那么这时是舍而不是入

如果负数的小数位超出 0.50 (比如 0.51) 才是入

三. 理解立即执行函数内部的 var a = b = 1

首先,该句等价于

b = 1
var a = b

其次,在一个封闭的作用域内,没有 var 声明的变量将成为全局变量(若未找到该变量),有 var 的成为局部变量

因此,最终结果是:生成一个全局变量 b,生成一个作用域内的变量 a

用一个 demo 说明以上:

!(function() {
    var a = b = 1
    console.log(b)
    console.log(a)
})()
// 1
// 1
console.log(b)
// 1
console.log(a)
// error

四. 变量提升的一个陷阱

有一段代码

(function() {
    var x=foo();
    var foo = function foo() {
    return 1
    };
    return x;
})();

按理说应该输出 1,

但是却报错 foo is not a function

原因在于第三行,变量会提升,但是赋值不会,内部相当于

var x
var foo
x = foo() // 就是在这一步, foo === undefined
foo = function foo() {}

改成这样就不会报错

(function() {
    var x=foo();
    function foo() {
    return 1
    };
    return x;
})();

虽然早已知道变量提升,但不得不说这道题的陷阱还是藏得有点深的。之前还以为是函数定义出了问题。

五. 细节

  • mouseleavemouseout 的区别是:前者不冒泡,后者冒泡
  • false == null 是 false
  • require 的模块查找顺序,参考
  • onclick 在标签的属性值是一个可执行脚本

    <button onclick="func()">a</button>
    <button onclick="document.querySelector('a').click()"></button>

金句

  • Date.now 和 Date.getTime 都是获取数字形式的日期
  • Math.round 处理 -0.5 是舍,处理 -0.51 是入
  • 在一个封闭的作用域内,没有 var 声明的变量将成为全局变量(若未找到该变量)
  • false == null 是 false
  • var a = b = 1 等价于 b = 1; var a = b
  • onclick 属性值是脚本