栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

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

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JavaScript“ 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)(...)
varindirecteval = 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

这个很棘手。评估评估码时,

this
obj
。但是,在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);


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/393950.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号