Hello 各位小伙伴 好久不见!
最近也是很久没有更新文章了,正好这段时间有空,我们来研究一些原生js的this指向问题
在开始之前,我们一起来看一道题目,代码如下:
const obj = {
a: 1,
fun: function(){
console.log(this)
function test(){
console.log(this)
}
test()
}
}
obj.fun()
大家看一下这两个this的结果呢,想必大家都知道第一个this的结果,但是对于第二个this,可能有些小伙伴会有疑惑。下面让我们来一起看一下结果
进入正文
这次我们会一起讨论到4个关于this指向的问题,以及更改this指向的方法,以及这个方法的用法
一:this的默认绑定与函数的独立调用
在我们的js代码运行之前,我们的代码会进行预编译,会创建我们的Go(global Object)
与Ao(area Object)对象,this的默认绑定为我们的golbal Object的window对象(浏览器环境)
(注意:this的默认绑定与执行环境有关系,如果是node环境,this指向的是引入的全局模块)
同时我们创建的变量与函数都是在window对象下的。所以为什么我们可以直接通过 fun() 的形式
进行函数调用(独立调用的方式)
所以总结起来,只要是函数的独立调用那么这个this就是指向函数的全局window
二:隐式规则,谁调用this就指向谁
这个大家都清楚吧,谁调用就指向谁。
const obj = {
fun: function(){
console.log(this) //指向obj
const test = () =>{
console.log(this) //指向obj箭头函数没有this,这里的this指向父级作用域的this
}
// 小伙伴们注意了,这里的test场景经常用哦
}
fun1: () =>{
console.log(this) //指向window 箭头函数没有this,这里的this指向父级作用域的this
}
}
这里还有一个问题就是存在this指向隐式转换的问题
const obj = {
fun: function(){
console.log(this)
}
}
obj.fun() // 这里打印出来的this指向obj
当我们做如下操作后
const test = obj.fun
test() // 这里的this指向window
这里就是test是一个函数,这个函数是obj.fun的深拷贝,当我们调用的时候,test这个方法,即为
独立调用,那么指向window,这里就是this隐式转换的问题
三:显示规则,使用call apply bind 进行显示的this绑定
我们先来说一下call apply bind方法的用法与区别
这三个方法都是将我们方法的this指向指定给某一个确定的对象,但是对于参数的传递是不同的
call方法的传递参数直接在第一个参数后写
一:call方法如下
const obj = {}
function test(a){
console.log(this)
}
test() // this指向window
test.call(obj,1) // 这里this指向obj,1为我们需要传递的参数,如果有多个往后写即可
如果我们在调用call方法的时候,没有传递this指向的对象,那么它会默认到我们传递的参数原型对象
如下
test.call(1) // 这里this指向js顶层的number对象
test.call('str') // 这里this指向js顶层的string对象
test.call() // 这里没有传递,默认指向window
二:apply 方法
const obj = {}
function test(a){
console.log(this)
}
test() // this指向window
test.apply(obj,[1]) // 这里this指向obj,1为我们需要传递的参数,但是传递的参数是
用[]进行包裹的,同样当我们没有传递参数的时候,它会默认到我们传递的参数原型对象
test.apply([1]) // 这里的this指向[1]这个数组
test.apply() // 这里的this指向window
三:bind方法
const obj = {}
function test(a){
console.log(this)
}
test() // this指向window
test.bind(obj)(1) // this指向obj,这里的bind类似于我们HOF(高阶函数)写法,当我们
传递参数的时候,再绑定的后面加一个括号进行我们的参数传递,同样当我们没有传递的时候
它会默认到我们传递的参数原型对象
test.bind()(1) // this这里指向window
test.bind(1)(1) // 这里this指向js顶层的number对象
test.bind('str')(1) // 这里this指向js顶层的string对象
四:通过构造函数或者class(es6)的new方法的this绑定
通过构造函数或者class(es6)的new方法的this,即为我们的实例对象
const test(){
this.fun = function(){
console.log(this)
}
}
const obj = new test()
obj.fun() // this 指向我们的实例对象obj
]
class test {
constructor () {
this.a = 1
}
fun(params) {
console.log(this)
}
}
const obj = new test()
console.log(obj)
obj.fun() // this这里指向我们的实例对象obj
总结
以上就是我们js中this重难点的所有问题了,希望大家看了文章后,有所收获,并运用到我们的实际工作中