JavaScript 的 this 是什么?

this

理解 JS 的 this 实际上非常简单,只需要了解 call 就行了

接下来,我们都使用 call 来调用函数,这才是最原始的函数调用方式

function foo() {
	'use strict'
	console.log(this)
	console.log(arguments)
}

foo.call()
foo.call({name: 'nada'})
foo.call({name: 'nada'}, 1, 2, 3)

上面三次调用打印的内容如下
js call
可以看到,当我们什么都不传入的时候 thisundefined,而当我们传入一个对象作为第一个参数时,this 就是这个对象

Arguments 对象是其它参数组成的一个伪数组

现在,你已经知道 this 就是 call 调用时传入的第一个参数,那么 this 到底有什么用呢 ?正常调用函数时为什么没传 this

我们不使用 this 写一段代码感受一下

const person = {
	name: 'nada',
	greet(person) {
		console.log(`Hey, I'm ${person.name}`)
	}
}

person.greet(person)

是不是非常麻烦,person.greet(person) 这种代码怎么看都是重复的

正常的代码应该是这样的 person.greet()

但是如果这样的话,没有参数传递给 greet() 这个函数,函数中当然也不能访问 person 对象

这种问题在编程语言层面很容易解决,当你以这样的语法调用函数时 person.greet() ,JS 将前面那个对象作为参数传给函数就好了

所以,fn.call() 这种方式才是最存粹的函数调用,fn.call() 需要将 this 显式的作为参数传入,而我们平时写的 fn() 都由 JS 施加了魔法,this 被隐藏了起来,你不能指定 this 代表的对象,而是 JS 按照规则自动传入

既然调用时没传参数,那声明时就也不要写 this 了,不然不一致,语言的一致性是很重要的,最后就变成了下面这样,这也是我们平时代码的样子

const person = {
	name: 'nada',
	greet() {
		console.log(`Hey, I'm ${this.name}`)
	}
}

person.greet()

Python 在这种问题上就采取了不同的设计,Python 中类的方法的第一个参数永远是 self,这样的话,调用和声明就出现了不一致,不过这种不一致还可以接受吧

函数和对象本无关系,函数负责逻辑,对象负责数据,但是面向对象编程中,将对象(数据)和函数封装在一起,这种情况下,函数只为某些对象服务,函数和对象就需要有一定的关联,函数就需要一个上下文

然而函数本质只有输入和输出,没有上下文

因此 this 就作为函数的参数为函数带来了上下文,这个上下文就是一个对象,函数内部就可以通过 this 关键字访问这个对象的属性

this 其实就是连接函数和对象的桥梁

最后再来看一些示例吧

const person = {
	name: 'nada',
	foo() {
		console.log(this)
	}
}

person.greet()

这里调用 person.foo() 后打印的 this 当然是 person 对象

const bar = person.foo
bar()

调用 bar() 打印的 thisWindow 对象

person.foo.call({name: 'nono'})

这时,this{name: 'nono'}

这很清楚的说明了,this 正像上面所述,是动态传入的参数

而不是将一个函数作为一个对象的属性,这个函数的 this 就一定是这个对象

函数和对象本质上并无关联

this 是什么,只有调用时才能确定

如果面试官拿着下面这样的只有声明的代码问你 this 是什么,那你只能回答说没人能知道

const person = {
	name: 'nada',
	foo() {
		console.log(this)
	}
}

回调函数

回调函数的 this 指向是一个问题,当我们调用 person.foo() 时就知道 this 就是前面的 person ,当我们调用 bar() 时,也知道 thisundefined

但是回调函数的 this 是什么,我们是不能推断出来的,不过看下文档或是直接打印一下看看就好了

document.addEventListener('click', function () {
	console.log(this)
})

箭头函数

在一些情况下,一不小心就到导致错误的 this

const person = {
	name: 'nada',
	foo() {
		return function () {
			console.log(this.name)
		}
	}
}
const bar = person.foo()
bar() // undefined

这里调用 bar() 传给 this 的是 Window 对象

但 ES6 的箭头函数帮助我们解决了这些问题

箭头函数的 this 是在创建时就绑定的

const person = {
	name: 'nada',
	foo() {
		return () => {
			console.log(this.name)
		}
	}
}
const bar = person.foo()
bar() // 'nada'

上面的箭头函数是在 person 对象中的,所以它的 this 就绑定了 person 对象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值