当前位置: 首页 > 面试题库 >

JavaScript“ this”关键字如何工作?

公冶光亮
2023-03-14
问题内容

“ this”关键字如何工作?


问题答案:

[§11.1.1]的this关键字

所述this关键字的计算结果为当前执行上下文的ThisBinding的值

这个绑定是JavaScript解释器在评估JavaScript代码时所维护的,例如特殊的CPU寄存器,其中包含对对象的引用。每当在以下三种情况之一中建立执行上下文时,解释器都会更新ThisBinding:

1.初始全局执行上下文

在顶级代码中评估的JavaScript代码就是这种情况,例如,直接在内时<script>

<script>
  alert("I'm evaluated in the initial global execution context!");

  setTimeout(function () {
      alert("I'm NOT evaluated in the initial global execution context.");
  }, 1);
</script>

在初始全局执行上下文中评估代码时,ThisBinding设置为全局对象window

输入评估码

  • …通过直接调用eval() ThisBinding保持不变;它与调用执行上下文的[ThisBinding](第[10.4.2](2)(a)节)的值相同。

  • …如果不是通过直接调用eval()
    ThisBinding ,则将其设置为全局对象 ,就像 在初始全局执行上下文中执行一样(第10.4.2(1)节)。

§15.1.2.1.1定义了直接调用eval()是什么。基本上eval(...)是直接调用,而(0, eval)(...)var indirectEval = eval; indirectEval(...);则是的间接调用eval()

输入功能码

调用函数时会发生这种情况。如果在某个对象(例如in
obj.myMethod()或等效对象)中调用了函数obj["myMethod"](),则ThisBinding设置为该对象(obj示例中;第[13.2.1节])。在大多数其他情况下,ThisBinding设置为全局对象(第[10.4.3节])。

之所以写“在大多数情况下”,是因为有八个ECMAScript
5内置函数可以在参数列表中指定ThisBinding。这些特殊函数采用一个所谓thisArg的形式,当调用该函数时(第[10.4.3节]),它成为[ThisBinding]。

这些特殊的内置函数是:

  • Function.prototype.apply( thisArg, argArray )
  • Function.prototype.call( thisArg [ , arg1 [ , arg2, ... ] ] )
  • Function.prototype.bind( thisArg [ , arg1 [ , arg2, ... ] ] )
  • Array.prototype.every( callbackfn [ , thisArg ] )
  • Array.prototype.some( callbackfn [ , thisArg ] )
  • Array.prototype.forEach( callbackfn [ , thisArg ] )
  • Array.prototype.map( callbackfn [ , thisArg ] )
  • Array.prototype.filter( callbackfn [ , thisArg ] )

对于Function.prototype函数,它们是在函数对象上调用的,而不是将ThisBinding设置为函数对象,而是将ThisBinding设置为thisArg

对于Array.prototype函数,callbackfn在执行上下文中调用给定,thisArg如果提供,则将ThisBinding设置为;否则,转到全局对象。

这些是纯JavaScript的规则。当您开始使用JavaScript库(例如jQuery)时,您可能会发现某些库函数会操纵的值this。这些JavaScript库的开发人员这样做是因为它倾向于支持最常见的用例,并且该库的用户通常会发现此行为更加方便。当传递引用this库函数的回调函数时,您应参考文档以获取有关this调用该函数时值的任何保证。

如果您想知道JavaScript库如何处理的值this,则该库只是使用接受的内置JavaScript函数之一thisArg。您也可以使用回调函数和编写自己的函数thisArg

function doWork(callbackfn, thisArg) {
    //...
    if (callbackfn != null) callbackfn.call(thisArg);
}

我还没有提到一个特殊情况。通过new运算符构造新对象时,JavaScript解释器会创建一个新的空对象,设置一些内部属性,然后在新对象上调用构造函数。因此,在构造函数上下文中调用函数时,的值this是解释器创建的新对象:

function MyType() {
    this.someData = "a string";
}

var instance = new MyType();
// Kind of like the following, but there are more steps involved:
// var instance = {};
// MyType.call(instance);

Arrow functions

[Arrow functions](在ECMA6中引入)更改的范围this。参见现有的规范问题,[Arrow functions与函数声明/表达式:它们是否等效/可互换?]想要查询更多的信息。简而言之:

Arrow functions没有自己的this....绑定。相反,这些标识符像任何其他变量一样在词法范围内解析。这意味着在Arrow functions数中,this…指的是this在其中定义Arrow functions的环境中的值。

用一些例子便于你的理解

要显示答案,请将鼠标悬停在浅黄色框上。

  1. this标记的行的值是多少?为什么?

window —在初始全局执行上下文中评估标记的行。

    if (true) {
    // What is `this` here?
}
  1. 执行this时标记行的值obj.staticFunction()是多少?为什么?

obj —在对象上调用函数时,ThisBinding设置为该对象。

    var obj = {

    someData: "a string"

};



function myFun() {

    return this // What is `this` here?

}



obj.staticFunction = myFun;



console.log("this is window:", obj.staticFunction() == window);

console.log("this is obj:", obj.staticFunction() == obj);
  1. this标记的行的值是多少?为什么?

window

在此示例中,JavaScript解释器输入功能代码,但是由于未在对象上调用myFun/
obj.myMethod,因此ThisBinding设置为window

这与Python不同,在Python中,访问method(obj.myMethod)会创建一个绑定的方法对象。

    var obj = {

    myMethod: function () {

        return this; // What is `this` here?

    }

};

var myFun = obj.myMethod;

console.log("this is window:", myFun() == window);

console.log("this is obj:", myFun() == obj);
  1. this标记的行的值是多少?为什么?

window

这个很棘手。评估评估码时,thisobj。但是,在eval代码中,myFun未在对象上调用,因此将ThisBinding设置为window进行调用。

    function myFun() {
    return this; // What is `this` here?
}
var obj = {
    myMethod: function () {
        eval("myFun()");
    }
};
  1. this标记的行的值是多少?为什么?

obj

该行myFun.call(obj);正在调用特殊的内置函数Function.prototype.call(),该函数接受thisArg作为第一个参数。

    function myFun() {

    return this; // What is `this` here?

}

var obj = {

    someData: "a string"

};

console.log("this is window:", myFun.call(obj) == window);

console.log("this is obj:", myFun.call(obj) == obj);


 类似资料:
  • 本文向大家介绍“ this”关键字在JavaScript中如何工作?,包括了“ this”关键字在JavaScript中如何工作?的使用技巧和注意事项,需要的朋友参考一下 在JavaScript中,此关键字用作引用,以引用执行的代码的对象或主题。 示例

  • 问题内容: 我刚刚遇到了一个有趣的JavaScript情况。我有一个类,该类的方法使用对象文字表示法定义了多个对象。在这些对象内部,正在使用指针。从程序的行为,我推断出指针是指向在其上调用方法的类,而不是由文字创建的对象。 尽管这是我期望的工作方式,但这似乎是任意的。这是定义的行为吗?跨浏览器安全吗?是否有任何推理依据说明它超出了“规格说明”的范围(例如,这是某些更广泛的设计决策/理念的结果)吗?

  • 本文向大家介绍Javascript this 关键字 详解,包括了Javascript this 关键字 详解的使用技巧和注意事项,需要的朋友参考一下 一、this指向构造函数实例化对象 在上篇文章中,我们提到了使用new和不使用new调用构造函数的区别,如下例: 当构造函数当做普通函数被调用时,并没有返回值,同时this指向全局对象。那么我们如何来避免因为缺少new关键字,而产生的问题呢? 在上

  • 问题内容: 在下面的代码片段中,结果确实令人困惑。 结果是 为什么“ this”在父亲构造函数中指向Son,而“ this.x”却指向父亲在构造函数中的“ x”字段。“ this”关键字如何运作? 我知道 多态的 概念,但是[1]和[2]之间没有区别吗?触发 新的Son() 时,内存中发生了什么? 问题答案: 默认情况下,所有成员函数在Java中都是多态的。这意味着当您调用this.toStrin

  • 涵义 this关键字是一个非常重要的语法点。毫不夸张地说,不理解它的含义,大部分开发任务都无法完成。 前一章已经提到,this可以用在构造函数之中,表示实例对象。除此之外,this还可以用在别的场合。但不管是什么场合,this都有一个共同点:它总是返回一个对象。 简单说,this就是属性或方法“当前”所在的对象。 this.property 上面代码中,this就代表property属性当前所在

  • 本文向大家介绍javascript的this关键字详解,包括了javascript的this关键字详解的使用技巧和注意事项,需要的朋友参考一下 this 的定义 表示当前执行代码的环境对象  因此可将 this 的剖析分为“全局环境” 和 “函数环境” 两种类型的环境对象 全局环境 函数环境 在函数内部,this 的取值取决于函数被调用时的运行环境。 这里涉及到内存里的数据结构相关的知识点,当我们