温故而知新:重新认识JavaScript的this

Posted Yangder

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了温故而知新:重新认识JavaScript的this相关的知识,希望对你有一定的参考价值。

温故而知新:重新认识javascript的this

thisJavaScript中的一个关键字,关于讲解this的文章,网上资源很多。这里记录关于this的思考:什么是this、为什么有this

什么是this

this是描述函数执行的记录中的一个属性,只能在函数内部被访问到,会在函数执行过程中被用到。

看规范中定义的抽象操作Call(F, V [, argumentsList])

The abstract operation Call is used to call the [[Call]] internal method of a function object. The operation is called with arguments F, V, and optionally argumentsList where F is the function object, V is an ECMAScript language value that is the this value of the [[Call]], and argumentsList is the value passed to the corresponding argument of the internal method. If argumentsList is not present, a new empty List is used as its value.

执行Call操作的时候已经传进去了this值,那再看下相关表达式Function Calls的说明:

...
4.Let ref be the result of evaluating memberExpr.
...
9.Return ? EvaluateCall(func, ref, arguments, tailCall).

转到EvaluateCall:

1.If Type(ref) is Reference, then
    a. If IsPropertyReference(ref) is true, then
        i. Let thisValue be GetThisValue(ref).
    b. Else the base of ref is an Environment Record,
        i. Let refEnv be GetBase(ref).
       ii. Let thisValue be refEnv.WithBaseObject().
2.Else Type(ref) is not Reference,
    a. Let thisValue be undefined.

看这是在描述this的值如何确定,而EvaluateCall的入参是没有this。这么来看的话,可以理解,this是函数执行时,内部过程中的某个属性。即开头的结论:this是描述函数执行的记录中的一个属性,只能在函数内部被访问到

为什么有this

为什么会有,可以思考this的使用,解决了什么问题?

You Don\'t Know JS: this & Object Prototypes中这么解释的:

this提供了一种更优雅的方式来隐式“传递”一个对象引用,因此可以将API设计得更加简洁并且易于复用。

function identify() {
  return this.name.toUpperCase();
}

function speak() {
 var greeting = "Hello, I\'m " + identify.call(this);
}

var me = { name: "Kyle" };
var you = { name: "Reader" };

identify.call(me); // KYLE
identify.call(you); // READER

speak.call(me); // Hello, I\'m KYLE
speak.call(you); // Hello, I\'m READER

(⊙o⊙)…尝试从这个单词本身思考下,this应该是作为一个代词,那就应该是起代替或指示作用,this用于近指。那指代的是什么呢?那就又得回到ECMAScript规范:

The base value component is either undefined, an Object, a Boolean, a String, a Symbol, a Number, or an Environment Record. A base value component of undefined indicates that the Reference could not be resolved to a binding. The referenced name component is a String or Symbol value.

这么来看,this指代的事物的值可能性还蛮多的。考虑下,如果undefined, an Object, a Boolean, a String, a Symbol, a Number这些值,大可使用个标识符表示即可,没必要用到this

所以,大胆猜测,this是不是指代environment record,而且还是就近的environment record???

参考资料

  1. You Don\'t Know JS: this & Object Prototypes
  2. What is “this” keyword in JavaScript?
  3. How does the “this” keyword work?
  4. JavaScript深入之从ECMAScript规范解读this
  5. JS this
  6. this 的值到底是什么?一次说清楚

以上是关于温故而知新:重新认识JavaScript的this的主要内容,如果未能解决你的问题,请参考以下文章

温故而知新 - 重新认识JavaScript的Execution Context

温故而知新--JavaScript书摘

重新认识一遍JavaScript - 2

JavaScript之闭包(重新认识)

重新认识一遍JavaScript

以“有用”为圆心:重新认识智慧城市的“高手之路”