前语
只要你踏入JavaScript
的世界,那么你一定会遇到 this
要害词。有许多人所 this
是 JavaScript
中最杂乱的东西之一,也有人说 this
其实很简略……可是事实的确,有许多工作了好多年的小伙伴,在 this
指向问题上也常常出现过错。
总归,咱们本篇文章的目的便是为javascript百炼成仙免费阅读了让咱们彻底了解 this
,遇到 this
不再惧怕!
1.为什么要有 this?
已然 this
这么多小伙伴都觉得难,那为什么还要运用javascript它呢?依据哲学思想:存在即合理。已然 this
被提了出来,那么它肯定协助咱们处理了一些问题,又或许提升了开发效率。
咱们先运用测试用例一句比较官方的一句话来总结 this
处理了什么问题。
较为官方的解说:
this
被主动界说在所有前端开发函数的效果域中,它提供了一种更好的办法来“前端开发工程师工作内容隐式”的传递目前端开发标引证,这样使得咱们的API
设计或许函数变得愈加简练,并且还更简略复用。
看了上面那样官方的一段话是不是感觉脑子变成了一团浆糊,没看懂要紧。咱们可以结合一段代码再来了解。
代码如下:
function say() {
console.log("你好!", this.name);
}
let person1 = {
name: '小猪讲堂'
}
let person2 = {
name: '张三'
}
say.call(person1); // 你好! 小猪讲堂
say.call(person2); // 你好! 张三
上面这段代码十分简前端开发需要掌握什么技术略,咱们在函数内部运用了 person1
和 persjavascriptonjavascriptdownload2
目标中的那么特色,可是咱们的函数实践上并没有接纳参数,而是调用 this
隐式的运用了 name
特色,即隐式运用上下文目标测试中 name
,JavaScript咱们使用了 call
办法将函数内部的 this
指向了 person1
和 person2
,这浏览器的历史使得咱们的函数变得简练且简略复用。
咱们想一想,假如咱们没有 this
,那么咱们就需求显式的将上下文目标传入函数,即显式传入 person1
和 person2
目标。
代码如下:
function say(context) {
console.log("你好!", context.name);
}
let person1 = {
name: '小猪讲堂'
}
let person2 = {
name: '张三'
}
say(person1); // 你好! 小猪讲堂
say(person2); // 你好! 张三
上段代码中没有运用 this
,所以咱们直接显式的将上下文目标传入了函数,尽管现在代javascript高级程序设计码看起来不杂乱,测试你适合学心理学吗可是随着咱们的业务逻辑逐步浏览器推荐杂乱,或许说函数变得杂乱起来,那么咱们传入的 context
上下文目标上下文什么意思只会让代码变得越来越混乱。
可是假如咱们运用了 this
,便不会这样,条件是咱们需求清楚的知道 this
指代的上下文目标是谁。
当然,假如你对上面的代码不太了解,别急,慢慢来,看完本篇文章!
2.this 过错的了解
关于许多初学者,刚开始接触到 this
要害词时,常常踏入许多上下文什么意思误区。很大一部分原因的确是由于上下文图 this
有许多坑,可是终究原因仍是没有搞懂 this
的指向原理。这儿咱们举出初学者浏览器历史上的痕迹在哪里常见的 this前端开发有前景吗
误区,也是许多面试题里边常常喜爱挖坑的当地。
2.1 this 指向函数自身?
这一javascript什么意思个误区是许上下文字间距怎么调多初学者都会踏入的,毕竟 this
要害词英译过来便是“这儿”的意思,咱们在函数里边运用 this
,理所当然任务 this
指代的上下文什么意思是当前函数。
可是事实果真如此吗?咱们一同来看一段代码。
代码如下:
function say(num) {
console.log("函数履行:", num);
this.count++;
}
say.count = 0;
say(1); // 函数履行:1
say(2); // 函数履行:2
say(3); // 函数履行:3
console.log(say.count); // 0
上段代码中咱们给 say
函数添加了一个 count
特色,由于在 JS
中函数也是一个目标。然后咱们履行了 3
次函数,并且每次履行都调用了 count++
。
假javascript高级程序设计如咱们认为 this
指向的是函数javascript:void(0)自身,那么this.count+上下文英语+
履行的便是say.count
,所以按理来说咱们终究打印 say.count
成果应该是3
,可是浏览器的历史成果却是0
。阐明thisJavaScript.count
并不是say.count
。前端开发
所以咱们终究得出结论:say 函数内部的 this 并不履行函数自身!
那么咱们上段代码中的 this.count
是哪里的 count
呢?实践上履行this.count+上下文字间距怎么调+
的时分,会声明一个大局变量 count
,至于为什么,本篇文章和后面会解说。
打印 count:
console.log(say.count); // 0
console.log(count); // NaN
2.2 this 效果域问题
效果域也是 JS
中浏览器怎么打开网站比较难的知浏览器下载识点之一了,咱们这儿不会展浏览器历史记录设置开说效果域测试英文问题。咱们只给出 this
指向在效果域方面的误区,这个误浏览器网站删除了怎么恢复区许多初学者乃至前端开发和后端开发有什么区别好多年经验的开发者也会javascript什么意思踏入此误区。
咱们可以先来看一段十分经典的代码:
function foo() {
var a = 2;
this.bar();
}
function bar() {
console.log(this.a);
}
foo(); // undefined
上段代码中咱们在 foo
函数内部运用 this
调用了 bar
函数,然后在 bar
函数内部测试工程师打印 a
变量,假如咱们依照效果域链的思想考虑的话,此刻的 a
变量按道理是可以读取到的,可是事实却是 undefined
。
形成上述问题的原因有多个,其间有一个便是 this 在任何状况下都JavaScript不指向函数的词法效果域,上段代码就运用运用 this
将 foo
和 bar
函数的词法效果域测试手机是否被监控联通,这是不可行的。
至于词法效果测试手机是否被监控域是什么,这儿不展开说,需求咱们自行下去学习,简略来说词法效果域是由你在写代码时将变量和块效果域浏览器下载写在哪来决定的。
3.this 的界说
看了前面两章节,咱们大约能了解 this
是什么?它其实便是一个履行上下文中的一个特色,咱们也可以简略的把 this
当作一个目标,只不过该目标指向哪儿是在函数调用的时分确浏览器历史记录设置认的。
咱们简略总结一下 this
的特色:
-
this
是在运行时绑定的,不是在编写时联系上下文绑定 -
this
的绑定与javascript高级程序设计函数的声明和方位没有任何联系 - 函数在调用时,会创立一个履行上下文,
this
便是这个履行上下文中的一个特色,在函数浏览器怎么打开网站履行的时分可以用到this
。浏览器的历史记录在哪所以this
是在函数调用的前端开发需要学什么时分确认绑定联系的,也便是运行时。
所以,总结出来大约就一句话:
this
便是一个目标,this
是在函数被调用时发生的绑定,它javascript百炼成仙免费阅读指向什么完全取决于函数在哪里被调用。
4.this 绑定规矩
到这儿咱们知道了 this
的绑定是在函数调用的时分确认的,以及 this
不指向函数自身javascript百炼成仙等等问题。那么,函数在某个方位被调用时,咱们怎么确认 this
该绑定到哪里呢?这个时分咱们就需求一些绑定规矩来协助咱们清晰 this
绑定到哪里了,当然,想要运用绑定规矩的条件是,咱们需求知道函数的调用方位javascript面试题。
有些状况下,函数的调用方位咱们可以直接观察测试工程师出来,可是有些状况稍显杂乱,这个时分咱们就需求凭借调用栈来来分析出函数的实践调用方位了。
咱们可以经过浏览器来检查调用栈,简略测试抑郁程度的问卷来说调用栈就相当于函数的调用链,和效果域链有异曲同工之妙,只是咱们直接看代码分测试用例析或许不太简略执行上下文。所以咱们可以经过打断点的办法,然后凭借浏览器来检查调用栈,如下图所示: 调用栈的详细用法还需求咱们下来仔前端开发工资一般多少细学习。
接下上下文英语来就来学测试英文习详细的 this
绑定规矩。
4.1 默许绑定
咱们比较常见的一种函数调用类型便是独立函数的调用,形如f测试oo测试英文()
等。前端开发工资一般多少这个浏览器的历史记录在哪时分的 this
绑定便是选用的默许绑定规矩。
代码如下:
var name = '小猪讲堂';
function foo(){
console.log(this) // Window{}
console.log(this.name) // 小猪讲堂
}
foo(); // 小猪讲堂
上段浏览器历史记录设置代码十分简略,咱们在大局效果域中界说了一个变量name
,然后咱们在函联系上下文数 foo
中运用th测试抑郁程度的问卷is.name
,前端开发入门薪水输出的成果便是大局变上下文英语量name
,这阐明咱们 this
指向了大局效果域,也便是说 this
绑定到了 wind测试你适合学心理学吗ow
目标上。
输出成果:
函数的这种调用办法就被称为默许绑测试你的自卑程度定,默许绑定规矩下的 this
指向大局目标。
咱们可以给默许绑定进程上下文给个界javascript百炼成仙说:
当函数不带用任何修饰进行调用时,此刻
this
的绑定便是默许绑定javascript高级程序设计规矩,this
指向大联系上下文局目标。
留意:
let变量声明不会绑定在window上面,只有var声明的才会,这是需求留意的。除此之外,严厉方法下上段代码的 this
是 un上下文字间距怎么调defined
,比方下面这段代码:
var name = '小猪讲堂';
function foo(){
'use strict'
console.log(this.name)
}
foo(); // Uncaught TypeError: Cannot read properties of undefined (reading 'name')
从上段代上下文字间距怎么调码可以看出,默许绑定规矩下,this
绑定到了大局目标,当然这与函数调用方位有关。可是严厉方法下,this
的绑定与函数调用方位无关。
4.2 隐式绑定
前面的默许绑定规矩很好了解,由于咱们的函数履行上下文便是大局效上下文语境果域,this
自然而然绑定到了大局目标上。
独立函数的调用咱们可以直接看出履行上下文在哪里,但假如不是独立函数调用,比方下面代码。
代码如下:测试
function foo() {
console.log(this.name) // 小猪讲堂
}
let obj = {
name: '小猪讲堂',
foo: foo
}
obj.foo();
上段代码咱们在 obj
目标中引证了函数 foo
,然后咱们运用 obj.foo
(函数别名)的办法调用了该函数,此刻不是独立函数调用,咱们不能运用默许绑定规矩。
此刻 this
的绑定规矩称为隐式绑定规矩,由于咱们不能直接看出函数的调用方位,它的实践调用方位在 obj
目标里边,调用 foo
时,它的履行上下文浏览器怎么打开网站目标为 obj
目标,所以 this
将会被绑定到 obj
目标上,所以咱们函数中的 th前端开发有前景吗is.name
其实便是obj.name
。这便是咱们的隐式绑定联系上下文规矩。前端开发和后端开发有什么区别
留意:
假如咱们调用函数测试你适合学心理学吗时有多个引证调用,比方obj1.obj2.foo()
。这个时分函数 foo
中的 this
指向哪儿呢?前端开发有前景吗其实不管引证链上下文字间距怎么调多长,this
的绑定都由最顶层调用方位确认,即obj1.obj2.foo()
的 this
仍是绑定带 obj2
。
隐执行上下文式绑定中 thi浏览器历史上的痕迹在哪里s 丢掉
在隐式上下文图绑定规矩中,咱们认为谁调用了函数,t浏览器his
就绑定谁,比方 obj.foo
中 this
就绑定到 obj
,可是有一些状况比较特别,即便选用的隐式绑定规矩,可是前端开发软件 this
并没有依照咱们的想法去绑定,这便是所谓的隐式绑定 this
丢掉,常见于回调函数中。
代码如下:测试
function foo() {
console.log(this.name) // 小猪讲堂
}
function doFoo(fn) {
fn(); // 函数调用方位
}
let obj = {
name: '张三',
foo: foo
}
let name = '小猪讲堂';
doFoo(obj.foo); // 小猪讲堂
上段代码中咱们很简略会以为 foo
绑定的 this
是 obj
目标,由进程上下文于咱们运用了 obj.foo
的办法,这种办法便是遵循隐式绑浏览器推荐定规矩。可是事实上 this
却绑定到了大局目标上去,这是由于咱们在 doFoo
函数中调用 fn
时,这儿才是函前端开发和后端开发有什么区别数的实践调用方位,此刻是独立函数调前端开发用,所以 this
指向了大前端开发和后端开发有什么区别局目标。
实践项目中咱们简略遇到这种问题的场景或许便是定时器了,比方下面的代码:
setTimeout(obj.foo, 100)
这种写法就很简略形成 this
丢掉。
4.3 显式绑定
前面咱们现已说了默许绑定和隐前端开发工资一般多少式绑定,其间隐式绑定咱们通常是以 obj.foo
这种方法来调用函数的,目的便是为了让 foo
的 this
绑定到 obj
目标上。
这个时分,假前端开发工程师工作内容如咱们不想javascript高级程序设计经过javascript是干什么的 obj.foo
的方法调用函数,咱们想要很清晰的将函数的 this
绑定在某个目标上。那么可以运用 call
、apply
等办法,这便是所谓的显式绑定规矩。
代码如下:
function foo() {
console.log(this.name) // 小猪讲堂
}
let obj = {
name: '小猪讲堂',
}
foo.call(obj);
上段代码咱们使用 call
办法直接将 foo
函数内部的 this
指向了 obj
目标,这便是显式绑定。
尽管显式绑定让咱们很清楚的知道了函数中的 this
绑定到了哪个目标上,可是浏览器网站删除了怎么恢复它仍是无法结局浏览器历史上的痕迹在哪里咱们 thisjavascript权威指南
绑定丢掉的问题,就比方下面这种写法:
function foo() {
console.log(this.name) // 小猪讲堂
}
function doFoo(fn) {
fn(); // 函数调用方位
}
let obj = {
name: '张三',
foo: foo
}
let name = '小猪讲堂';
doFoo.call(obj, obj.foo); // 小猪讲堂
上段代码咱们尽管运用 call
来更改 this
绑定,可是终究成果却是没有用的。
尽管显式绑定自身不能处理 this
绑定丢掉的问题测试你的自卑程度,可是咱们可以经过变通的办法来处上下文什么意思理这个测试你的自卑程度问题,也被称作硬绑定。
硬绑定:
function foo() {
console.log(this.name) // 小猪讲堂
}
function doFoo(fn) {
fn(); // 函数调用方位
}
let obj = {
name: '张三',
}
let bar = function () {
foo.call(obj)
}
let name = '小猪讲堂';
doFoo(bar); // 张三
setTimeout(bar, 100); // 张三
其实思路也比较简略,出现 this
绑定丢掉原因无非便是咱们传入的回调函数在被履行时,this
绑定规矩变为了默许绑定,那么为了处理这个问题,前端开发软件咱们无妨在封装一个函数,将 foo
函数的 this
显式绑定到 obj
目标上去即可。
这儿提一点,下面写法是过错的:
doFoo(foo.call(obj));
由于回调函数是在 doFoo
里边履行的,上面的写法相当于 foo
函数当即履行了。
弥补:
其实咱们的 bind
函数上下文什么意思便是一个硬绑定,咱们想一想,bind
函数是不是创立一个新的函数,然后将 this
指定,是不是就和咱们下面这段代码执行上下文的效果一样。
let bar = function () {
foo.call(obj)
}
// bind 方法
let bar = foo.bind(obj)
4.4 new 绑定
new
要害词相信咱们都知道或许运用过吧,测试手机是否被监控这便是咱们将要将的第 4
种 this
绑定,叫做 new
绑定。
想要知道 new
绑定规矩,咱们就很有必要知道一个当咱们 new
一个目标的时分做了什么,或许说 new
要害词会做哪些操作。咱们这儿简略总结一下,详细的 new
的进程还需求咱们自行下来好好学学。
运用 new 来调用函数时,会履行下面操作:
- 创立一个全新的目标
- 这浏览器的历史记录在哪个新目标会被履行原型连接
- 这个新目标会绑定到函数调用的
this
- 假如函数没有返回其它目标,那么
new
表达式种的函数调用会主动返回这个新目标
咱们可以看到 new
的操作中就有 this
的绑定,咱们在浏览器历史上的痕迹在哪里来看看代码。上下文英语
代码如下:
function foo(name) {
this.name = name;
}
let bar = new foo('小猪讲堂');
console.log(bar.name); // 小猪讲堂
上段代码咱们运用 new
要害词调用了 fojavascript百炼成仙o
函数,上下文语境咱们留意这不是默许调用规矩,这是 new
绑定规矩。
5.优先级
前面咱们总结了测试仪 4 条 this
绑定的规矩,在大多数状况下咱们只需求找到函数的调用方位,然后再判浏览器数据如何恢复别选用哪条 this
绑定规矩,终究确认 this
绑定。
咱们这儿进程上下文可以先简略总结一下 4 条规矩以及 this
绑定确认流程。
this 绑定确认流程:
先确认函数调用方位,然后确认运用哪条规矩,然后依据规矩确认
this
绑定。
this 绑定规矩:
- 默许绑定:
this
绑定到大局目标 - 隐式绑定:一般绑定到调用目标,如
obj.foo
绑定到obj
- 显式绑定:经过
call
、apply
指定this
绑定到哪里- 硬绑定:运用
bind
函数
- 硬绑定:运用
-
new
绑定:运用new
要害词,绑定到当前函数目标
可以看到,咱们确认 this
绑定的时分有 4 条规矩,在通常状况下,咱们可以依前端开发入门薪水据这 4 条规矩来判别出 this
的绑定。可是有时分某个函数的调用方位对应了多个绑定规矩,这个时分咱们该选用哪一条规上下文字间距怎么调矩来确认 this
绑定呢?这个时分就需求清晰每一条绑定规矩的优先级了!
首要咱们要清晰的式默许绑定规矩的优先级是最低的,所以咱们考虑的时分暂时不考虑默许绑定规矩。
5.1 隐式绑定与显式绑定
假如函测试抑郁症的20道题数调用的时分出现了隐式绑定和显式绑定,那么详细选用哪一个规矩,咱们经过代码来试验一下。
代码如下:
function foo(){
console.log(this.name);
}
let obj1 = {
name: '小猪讲堂',
foo: foo
}
let obj2 = {
name: '李四',
foo: foo
}
obj1.foo(); // 小猪讲堂
obj2.foo(); // 李四
obj1.foo.call(obj2); // 李四
obj2.foo.call(obj1); // 小猪讲堂
上段代码中咱们触及到了两种 this
绑定,obj浏览器的历史.foo
为隐式绑定,this浏览器的历史记录在哪
绑定给 obj
目标,而 foo.call(obj)
为显现绑定,this
绑定给 obj
目标。
从上段代码看出,当两个绑定规矩都存在的时分,咱们选用的是显式绑定规矩。
总结:
显式绑定 > 隐浏览器历史上的痕迹在哪里式绑定
5.2 new 绑定与隐式绑定
接下来咱们看看 new
绑定与隐式绑定的优先级。
代码如下:
function foo(name) {
this.name = name;
}
let obj1 = {
foo: foo
}
obj1.foo('小猪讲堂');
let bar = new obj1.foo("张三");
console.log(obj1.name); // 小猪讲堂
console.log(bar.name); // 张三
上段代码中在在运用 new
要害词浏览器怎么打开网站的时分又运用了 obj1.foo
隐式绑定,可是终究成果 this
并没有绑定到 obj1
目标上,所以隐式绑定优先级低于 new
绑定。
总结:
隐式绑定 < new 绑定
5.3 显式绑定与 new 绑定
接下来咱们比较显式绑定与 new
绑定规矩,可是咱们 new
绑测试抑郁程度的问卷定与显式绑定的 call浏览器的历史记录在哪、apply
办法不能一同运用,所以咱们无法经过 new foo.前端开发软件call(前端开发obj)
来进行测试。
可是咱们前面解说javascript百炼成仙免费阅读显式绑定的时分,提到一种绑定叫做硬绑定,它也是显式绑定中的一种,所以说咱们可以使用硬绑定与 new
绑定来进行比较。
代码如下:
function foo(name) {
this.name = name;
}
let obj1 = {};
let bar = foo.bind(obj1);
bar('小猪讲堂');
console.log(obj1.name); // 小猪讲堂
let baz = new bar('张三');
console.log(obj1.name); // 小猪讲堂
console.log(baz.name); // 张三
上段代码中咱们把 obj
硬绑定到了 bar
上,然后咱javascript面试题们经过 new
绑定调用了函数,可是 obj1.name
仍是小猪讲堂,并没有改为张三,可是,咱们的 new
操作前端开发需要学什么修改了硬绑定(到 obj1
的)调用 bar
中的 this
。由于运用了 new
绑定,咱们得到了新的 baz
目标,并且 baz.name
为张三。
总结:
new上下文语境
绑定 > 显式绑定,需求留意的是,new
操作时将 this
绑定到了新创立的联系上下文目标。
6.this 绑浏览器网站删除了怎么恢复定总结
到这儿,咱们基本上可以确认一个函数内部的 this
指向哪儿了,咱们这儿做出一些总结,以供在项目实践中判别 this
绑定。
this 绑定规矩优先级:
默许绑浏览器的历史记录在哪定 < 隐式绑定 < 显式绑定 < new 绑定
判别 this 终究指向,总体流程:
- 判别函数调用时是否运用了
new
,即new
绑定,假如运用了,则thisjavascript面试题
绑定的是新创立的目标。 - 函数调用是否运用了
call
、apply
等显式绑定,或许硬绑定(bind),假如是的话,t前端开发工资一般多少his
指向指定的目标。 - 函数是否在某个上下文目标中调用,即隐式绑定,如
obj1.foo
,假如是的话,this
指向绑定的那个上下文目标。 - 以上 3 点都不触及的话,则选用默许绑定,可是需求留意的是,在严厉方法下,默许绑定的
this
是undefined
,前端开发是什么非严厉方法下绑定到大局目标。
结合上面的绑定优先级以及判别流程,咱们在一般的项目中以及可以判别出 this
指向哪儿了!
总结
this
绑定尽管是一个浏览器数据如何恢复比较难的知识点,可是咱们作为一个前端开发者,必需要学会怎么了解和运用它,由于它的确能给咱们带来许多的便利和优点。
当然,本篇文章只解说了最惯例的 this
绑定及原理,除此之外,this
绑定还有一些意外的状况测试抑郁症的20道题,这儿不做更多解说,感兴趣的小伙伴可以自行下来查询材料,比方说软绑定、直接引证等等。
总归,惯例判别如下:
- 由
new
调用函数,绑定到新目标 - 由
call
等调用,绑定到指定目标 - 由上下文目标功效,绑定到上下文目标
- 默许调用,绑定到大局目标或
und联系上下文efined
参考材料: 《你不知道的JavaScript》
我正在参与技javascript面试题能社区创作者签约方案招募活测试动,点击链接报上下文图名投稿。