• 原文地址:JavaScript: What is the meaning of this?
  • 原文作者:Jake Archibald
  • 原文发布时间:2021-03-08
  • 本文永GitHub久链接:github.com/Ivocin/Tran…
  • 翻译、校正:Ivocin

搞了解 Javaelement什么意思中文Script 中 this 的值有时候会很扎手,本文带你彻底搞懂 thielementary怎样读音s

JavaScript 的 this 往往javajavascript什么意思hdxx会成为许多笑话的笑柄,由于它恰当杂乱。可是,我发现许多开发人员为了防止处理 this,用了愈加杂乱javascript:void(0)和特定范畴的处理。假定你java面试题thisGitHub不了解,期望本文approach能协助到你。下面进入我的 this 攻略。

我将从最具体的状况开elementui菜鸟github敞开私库教程端,以elementary school最不具体的状况完毕,本文的结构相似与一个大的application ijavascript面试题f (github怎样读…) … else if () … else if (…) … 语句,所以你能够直接跳转java根底知识点到匹配你代码状况的章节。

  1. 假定是箭头函数
  2. 不然,假定运用 neGitHubw 调用函数/类
  3. 不然, 函javascript高档程序设计数被 bindtjava怎样读hijavascript菜鸟教程s
  4. 不然, 假定 this 在调用时设置
  5. 不然, 假定运用父政策(parenjava面试题t.func()) 调用函数
  6. 不然, 假javascript高档程序设计设函数或许其父效果域运element什么意思中文用严峻办法
  7. 不然

假定是箭头函数:

const arrowFunction = (github下载) => {
console.logElement(this);
};

在这种状况下,this 的值java难学吗与父效果域的 this 相同。

const outerThis = this;javahdxx
const arrowFjava是什么意思uncAPPtion = () =&gtjavascript; {
// 永久输出 `true`:
coelementsnsole.log(thiselement什么意apple思中文 === outerThis);
};

箭头app装置下载appreciate函数非常优秀,因github-zookeeper为其内部 this 的值无法被改动,它与外部的 this 永久 相同。

其他比如

运用箭头函数, this 的值github敞开私库无法bind 改动:

// 输出为 `true` - bjava根底知识点ind `this` 被疏忽:
arrowFunction.bind({foo: 'bar'})();

javascript菜鸟教程用箭头函数,this 的值无法callapply 改动:javascript数据类型

// 输出为 `true` - call `thisgithub怎样下载文件` 被javascript什么意思疏忽:
arrjavascript什么意思owFunction.call({foo: 'baelementary什么意思中文r'});java面试题
// 输出为 `true` - apply `thappearis` 被疏忽:
arrowFunction.apply({foo: 'bar'});

运用箭头函数,this 的值无法经过将函数作为另一个方javascript针的成员变量来调用改动:

celementary怎样读音onst obj = {arrowFunction};javascript:void(0)
//elementary是什么意思 输出为 `true` - 父政策被疏忽:
obj.arrowFunction();

运用箭头函数,this 的值无法经过将函数作为结构函数来调用而改动:

// TypeError: arrowFunction is not a constructor
new arrowFunctioapproachn();

“绑定” 实例办法

application于实例办法,假定想要保证 this 一向指向类实例,最好的办法是运用箭头函数和 cljavascript根底入门ass fields:

class WhatevElementer {javascript面试题
someMethogithub怎样读d = () => {
// 永久是 Whatever 的实例:
console.javascript面试题log(this);
};
}

这个办法在将实例办法作为组件内的作业监听器时非常有用(如 React 组件或许 Wejavascripgithub怎样读t浏览器b Components)。

上面的代码形似打破了“this 的值永久与父效果域的 this 相同”的规则,可是假定你将 class fields 看作将政策设置到结构函数的语法糖,那么就好了解了:

celementui菜鸟教程lass WhateGitHubver {
someMethod = (() => {
const outerThis = this;
return () => {
// 永久输出 `true`Java:
consoleGitHub.log(this === outerThis)javascript数据类型;
};
})();
}
// …大致等于:
class Whatever {
constructor() {
conappearancest outerThiselementagithub怎样读ry school = thgitjavascript数据类型hub永久回家地址is;
this.sappstoreojava怎样github敞开私库meMethod = () => {
// Always logs `true`:
capproachonsole.log(this === outerThis);
};
}
}

其他办法包含在结构函数中绑定现有函数,或在JavaScrelement翻译ipt结构函数中对函数赋值。假定你由于某种原因不能运用 class fields,则在结jajava根底知识点vascript根底入门构函数中对函数赋javascript根底入门值是一种appreciateelementary理的选择:github-zookeeper

claElementss Whatever {
constructor() {
this.someMetjavascripthod = () =java游戏&JavaScriptgtgithub中文官网; {
// …
};
}
}

不然,假定运app装置下载new 调用函数/类:

new Whatever();

上面代码会调用 Whatever(或许它的结构函数javaelementaryscrijavascript数据类型pt菜鸟教程,假定它是类),并将 this 设置为 Object.create(Whatevergithubcom1jie1小可爱.prappreciateototype) 的效果。

class MyClass {
constructor() {
console.log(
this.constructor === Object.create(MyClass.prototype).constructor,javascript什么意思
);
}
}
// 输出为 `true`:
new MyClass();

运用旧式的结构函数效果也相同:

funjava怎样读ction MyClass() {
conapplesole.ljava是什么意思og(
thgithub下载is.constructor === Object.create(MyClass.projavahdxxtotype)github中文官网.constructor,
);apprecapp装置下载iate
}
/javascript/ 输出 `true`:
new MyClass();

其他比如

运用 new 调用,javascripttGitHubhis 的值无法bappleidinappstored 改动:

const BoundMyClass = MyClass.bind({foo: 'bar'});
// 输出为 `true` - bGitHubind `this` 被疏忽:
new Boelement什么意思中文undMyClasgithub怎样下载文件s();

运用 new 调用,this 的值无法javahdxx过将函数作为另一个政策的成员变量来调用改动:

const obj = {Mygithub敞开私库Class};
// 输出为 `true` - 父政策被疏忽:
new obj.MyClass();

不然, 函数被javascript数据类型 bindthjava怎样读isjava面试题

function someFunction() {
returappgithub敞开私库earn this;
}
const boundObject = {hellojavascript浏览器: 'world'};
const boundFunctionjavahdxx = someFunction.bind(boundObject);

每逢 boundFunctioelementary怎样读音n 被调用,它的 this 值就是githubcom1jie1小可爱javascript高档程序设计经过 bind 传入的值(boundObappointmentjectappear

//Element 输出 `false`:
console.log(someFuappleidnction() === boundObjavascript面试题ject);
// 输出 `true`:
console.log(GitHubboundFunction() === boundObjectappointment);

Warning: 防止运用 bind 将函数绑定到其外部的 this。运用箭头函数替代,由于这样 this 能够在函数声明就能APP清楚地看出javascript菜鸟教程来,github-zookeeper而非在后续代码中看到。
不要运用 bind 设置 this 为与父政策无关的值;这通常是出其不意element是什么牌子的,这也是 this 获得如github中文官网此糟糕名声的原因。考虑将值作为参数传appointment递;element翻译它愈加清楚,并且能够运用箭头函数。

其他比如

APPbind 调用函数,this 的值无法caelementary怎样读音llapply 改动:

// 输出为 `true` - call `this` 被疏忽:
console.log(boElemejavascript浏览器ntundFunction.call({foo: 'bar'}) === boundObjejava难学吗ct);
// 输出为 `true` - apply `thiselementary怎样读音` 被疏忽:
console.log(bjavascript什么意思oungithub中文官网dFunction.apply({foo:appear 'bar'}) === bouJavandObject);

运用 bind 调用函数,thiapples 的值无法经过javascript什么意思将函数作为另一个政策的成员变量来调用改动:

const obj = {boundFuncjavascript菜鸟教程tappleidion};
// Logs `true` - parent object is ignored:
console.log(obj.boundFunction() === bappleidoundObject);

不然jajavascript是干什么的vascrelementuiipt菜鸟教程, 假定 this 在调用时设置:

function someFunction()element是什么牌子 {
rejavasjavascript什么意思cript菜鸟教程turn thisjava模拟器;
}
const someObject = {hello: 'world'};
// 输出 `true`:
console.log(soappearancemeFunction.call(someObject) ==javascript:void(0)= sogithub敞开私库meObject);
// 输出 `true`:
console.javascript根底app装置下载入门log(github-zookeepersomeFunction.apjavascript根底入门ply(someObject) === someObject);

this 的值就是传递给 call/apply 的政策。


正告: 不要运用 bind 设置 this 为与父政策无关的值;这通常是出其不意的,这也是 this 获得如javascript是干什么的此糟糕名声的原因。考虑将值作为参数传递;它愈加清楚,并且能够运用箭头函appstore数。

不幸的是,thielementary怎样读音s 或许会被如 DOM 作业监听器之类的函数设置为其他值,运用它会导致代码难以了解:

不要这javahdxx样:

element.addEventListener('github永久回家地址click', function (event) {
// 输出 `element`, 由于javascript是干什么的 DOM 将 `this` 设置为
// click 绑定的元素上
console.log(this);
});

appointment会防止在上述场景github-zookeepergithub敞开私库运用 this,我会这样运用:

element.addEventLijavascript浏览器stener('click', (event)github中文官网 =>elementary schoappearanceol {
// 志向状况, 从父效果域获得它:
conselement是什么牌子ole.log(element);
// 可是假定你不想这么做,能够从 event 政策获取它:
console.log(event.currentTargegithub官网t);
});

不然, 假定运用父政策(parenelement翻译tgitjavascript是干什么的hub下载.func()) 调用函数:

const obj = {
somgithub永久回家地址eMethod() {
return this;
},
};
// 输出 `true`:
console.log(obj.someMejavascript数据类型thod() === obj);

在这种状况下,函数作为 obj 的成员变量被调用,所以 this 指向 obj。这是在调用时产生的,因此假定java模拟器没有运用github怎样下载文件父政策调用,或许运用一个java面试题不同的父政策调用,该联接会断开elements

const {somelement翻译eMethod} = obj;
// 输出 `false`:
console.log(someMethod() === obj);
const anotherObj = {someMethod};
// 输出 `false`:
celementaryonsole.log(anotherObj.someMethod() === obj)javascript;
// 输出 `true`:
console.log(anothegithub永久回家地址rObj.sojavascript:void(0)meMethoelementary schoold() ===github中文官网 anojava根底知识点thElementerObj);

someMethod() === objava环境变量配备jfalse,由于 someMethod 不是javascript什么意思 作为 obj 的成员变量被调用的。查验实行以下操作时,或许elementui菜鸟教程会遇到此骗apple局:

const $ = document.querySelector;
// TypeError: Illegelementary怎样读音al invocation
const el = $('.some-element');

这个appointmentappleelement什么意思中文id错是由于 querySelector 完毕会寻觅它的 this 值,并期望javascript浏览器其某种 DOM 节点,上述代码破坏了联接。为了正确完毕上述功用,可github怎样读javascript高档程序设计以这样写:JavaScript

const $ = docelement翻译ument.querySelector.bind(document);
// 或GitHub许:
const $ = (...ajava根底知识点relement什么意思中文gs) => document.querySGitHubelector(...args);

幽默的现实:并不是全部的 API 都在其内部运用了 this。Coappstorensole 办法(如 console.log)就改为了不运用 this 引证,因此 log 办法不需要绑定 consolegithub下载


正告: 不要运用 bindjavascript根底入门 设置 this 为与父政策无关的值javascript高档程序设计;这通常是出其不意的,这也是 this 获得如此糟糕名声的原javaselementary怎样读音cript:void(0)因。考虑将值作为参数传递;它愈加清楚,并且能够运用箭头函数。

不然, 假定函数或许其父作elementary school用域运用严峻办法:

function someFunction() {
  'use strict';
return telementary schoolhis;
}
// 输出 `trueGitHub`:
consjava面试题ole.log(sjavascriptomeFJavaScriptuncelementary schooltion() === undefined);

在这种状况下,elementuithis 的值是 undefined。假定父效果域处于严峻办法(并且全部模块都处在严峻办法)javascript,则不需要在函数内部运用 'use strict'


正告: 不要依托这ajava难学吗pplication个。我的意思是,有更简略的办法来得到一个 undefijava名优馆在线六区ned 值 。

不然:github怎样读

funappointmentction someFunction() {
return this;
}
// 输出 `true`:
consgithub-zookeeperole.log(someFunction(appreciate) === globgithub下载appleidalThis);

在这种状况下,this 的值与 globalThis 相同。


javascript高档程序设计javascript多人(包含我)把 globalThis 称为 glelementui菜鸟教程obal 政策,但这不是 100% 技能正确的。在 Mathgithub中文官网ias Bynens with the details 中,有它为什么叫 globalThiselement翻译 而不是 global 的原因。


正告: 防止运appearthis 指向 global 政策(对,我依然这么叫它)。改为运用globalThis,它愈加清楚。

结语

好了,这就是我了解的 this 的悉数了。假定有任何问题或许我有所遗失,请给我发javascript面试题推。

感谢 Mathias Bynensapple, Ingvar Stepanyan, 和 Tgithubcom1jie1小可爱homas Steingithub下载erGitHub 的审理。

—- End —-

本文正在参加「 2021 春招闯关活动」, 点击检查 活动概略