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

  • promise 有几种状态
  • +[] 为何等于 0
  • setTimeout 为何不算 JS 的全局函数
  • 解决 this 的一个疑点
  • max 函数
  • 若干情形下的 undefined

promise 有几种状态?

promise 有三种状态: pending/resolve/reject。如下

function sleep() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if(Math.random() < .5) {
                resolve()
            } else {
                reject()
            }
        }, 2000)
    })
}

var t = sleep()
console.log(t)

+[] 为何等于 0?

这个涉及的东西比较绕,搜了一下,stackoverflow 上有一位老哥总结得很详细。所以直接引用他的答案

Specification details for +[]:

This is quite a maze, but to do +[], first it is being converted to a string because that's what +says:

11.4.6 Unary + Operator

The unary + operator converts its operand to Number type.

The production UnaryExpression : + UnaryExpression is evaluated as follows:

  1. Let expr be the result of evaluating UnaryExpression.
  2. Return ToNumber(GetValue(expr)).

ToNumber() says:

Object

Apply the following steps:

  1. Let primValue be ToPrimitive(input argument, hint String).
  2. Return ToString(primValue).

ToPrimitive() says:

Object

Return a default value for the Object. The default value of an object is retrieved by calling the [[DefaultValue]] internal method of the object, passing the optional hint PreferredType. The behaviour of the [[DefaultValue]] internal method is defined by this specification for all native ECMAScript objects in 8.12.8.

[[DefaultValue]] says:

8.12.8 [[DefaultValue]] (hint)

When the [[DefaultValue]] internal method of O is called with hint String, the following steps are taken:

  1. Let toString be the result of calling the [[Get]] internal method of object O with argument "toString".
  2. If IsCallable(toString) is true then,
  3. Let str be the result of calling the [[Call]] internal method of toString, with O as the this value and an empty argument list.
  4. If str is a primitive value, return str.

The .toString of an array says:

15.4.4.2 Array.prototype.toString ( )

When the toString method is called, the following steps are taken:

  1. Let array be the result of calling ToObject on the this value.
  2. Let func be the result of calling the [[Get]] internal method of array with argument "join".
  3. If IsCallable(func) is false, then let func be the standard built-in method Object.prototype.toString (15.2.4.2).
  4. Return the result of calling the [[Call]] internal method of func providing array as the this value and an empty arguments list.

So +[] comes down to +"", because [].join() === "".

Again, the + is defined as:

11.4.6 Unary + Operator

The unary + operator converts its operand to Number type.

The production UnaryExpression : + UnaryExpression is evaluated as follows:

  1. Let expr be the result of evaluating UnaryExpression.
  2. Return ToNumber(GetValue(expr)).

ToNumber is defined for "" as:

The MV of StringNumericLiteral ::: [empty] is 0.

So +"" === 0, and thus +[] === 0.

setTimeout 为何不算 JS 的全局函数

首先明确一点:

浏览器端的JavaScript包含ECMAScript,DOM对象以及BOM对象。

setTimeout 属于 BOM 对象,而我们说的 JS 全局函数若不在浏览器环境下一般指的是 ECMAScript

解决 this 的一个疑点

先看代码

var obj ={
    a:1,
    b:function () {
        alert(this.a)
    }
}; 
obj.b(); // 输出什么
var fun =obj.b; 
fun(); // 输出什么

我们都知道,对象调用自己的成员函数时,成员函数内部的 this 会指向调用它的对象

上面的代码令人困惑的是,如果我把成员函数的引用交给其他对象,再由其他对象调用这个函数时,this 的归属。

打印结果,第一次输出 1 (意料之中),第二次输出 undefined。据此,可以确定成员函数里 this 的归属,最终是由实际调用它的那一行语句中决定的。

因此: this 指向调用它的对象 !== 定义它的对象

更进一步,可以继续上面代码

var c = {a: 10}
c.b = obj.b
c.b()
// 输出 10

怎样,这下明白了吧

max 函数

有一个问题

var a = [1,4,5,2,9];
求a中最大值

首先

  • Math 对象有 max 方法,数组对象没有 max 方法

然后

  • Math.max 的语法是 Math.max(number1, number2, number3, ...)

所以,数组既不能直接调用 max 方法,也不能直接传给 Math 对象的 max 方法去调用

好在我们有 apply,允许用数组的方式传入参数列表

Math.max.apply(undefined, a)

搞定

若干情形下的 undefined

  • 函数,js 的函数总要返回些什么,如果我们没写返回语句,他就自作主张返回 undefined

    console.log(1)
    // 1
    // undefined
  • 声明语句,所有的声明语句都要返回 undefined

    var a = 1
    // undefined
    b = a
    // 1
  • 立即执行函数

    (function() {})()
    // undefined
    !(function() {})()
    // true

金句

  • promise 有三种状态
  • 浏览器端的JavaScript包含ECMAScript,DOM对象以及BOM对象
  • this 指向调用它的对象 !== 定义它的对象
  • 数组既不能直接调用 max 方法,也不能直接传给 Math 对象的 max 方法去调用