JS查漏补缺——神奇的this

简介: JS查漏补缺系列是我在学习JS高级语法时做的笔记,通过实践费曼学习法进一步加深自己对其的理解,也希望别人能通过我的笔记能学习到相关的知识点。这一次我们来理解一下面试题常考的this的指向

this在全局作用域下

在大多数情况下,this都是出现在函数中
在全局作用域下,this 的指向:

  • 浏览器:window( globalObject)
  • Node 环境:{ }
🤔有时候我们会发现JS执行this指向的结果会不一样,有什么规律吗?
this指向什么,跟函数所处的位置是没有关系的,而跟函数调用的方式有关系
function foo() {
  console.log(this);
}
var obj = {
  foo: foo
}
foo();  // 默认绑定
obj.foo(); // 隐式绑定
foo.call('a')  // 显式绑定

Snipaste_2022-09-03_13-44-26.png

this的默认绑定

当独立函数调用时,this 默认绑定(独立函数指函数没有被绑定到某个对象上进行调用)

function foo() {
  console.log(this);
}
var obj = {
  foo: foo
}
foo();  // 默认绑定

而默认绑定this在浏览器的指向是 window( globalObject)

this的隐式绑定

当通过某个对象发起的函数调用时,this 隐式绑定

function foo() {
  console.log(this);
}
var obj = {
  foo: foo
}
obj.foo(); // 隐式绑定

而隐式绑定this在浏览器的指向是 发起函数调用的对象(上面代码 this 的指向就是 obj 这个对象)
前提条件:必须在调用的对象内部有一个对函数的引用 (比如一个属性),不然会找不到函数而报错

var obj = {
  foo: foo
}
🤔如果不想要在对象上添加属性,但又想绑定这个对象要怎么办呢?
那就要用到显示绑定了

this的显示绑定——call/apply/bind

调用call/apply方法就可以手动地指定函数中this的指向对象

function foo() {
  console.log(this);
}
// foo.apply('a')
foo.call('a')  // 显式绑定

Snipaste_2022-09-03_14-38-59.png

🤔 call 和 apply 有什么区别呢?
如果只是单纯的指定对象,那他们的区别不大,它们主要的区别在于传递参数的形式

call 和 apply 的区别

这两个函数的第一个参数都要求是一个对象,后面的参数,call是参数列表,apply是数组

function sum(num1,num2) {
  console.log('this指向的对象为' + this, num1 + num2)
}
sum.call('call', 10, 20)
sum.apply('apply', [10,20])

Snipaste_2022-09-03_14-46-25.png

用bind来绑定

通过bind来绑定就不用一直调用call/apply方法来进行绑定(相当于用bind绑定一次可用多次)

function foo() {
            console.log(this);
}
var newFoo = foo.call('a')
newFoo()
newFoo()

Snipaste_2022-09-03_15-06-29.png

function foo() {
  console.log(this);
}
var newFoo = foo.bind('a')
newFoo()
newFoo()

Snipaste_2022-09-03_15-07-01.png

🤔这里就有一个问题了: newFoo( )是一个独立函数调用吧,那它为什么不是指向window而是指向 ‘a’
是因为如果默认绑定和显示绑定一起出现,则显式绑定起作用,显示绑定优先级更高

this的new绑定

除了上面的默认绑定、隐式绑定和显式绑定,我们还可以通过一个new关键字来绑定对象
当我们通过一个new关键字调用一个函数时(构造器),这个时候this是在调用这个构造器时的对象

function Pet(name,hobby){
    this.name = name
  this.hobby = hobby
}
var p1 = new Pet('三号楼', 'eat')
console.log(p1.name,p1.hobby)  //三号楼 eat

规则绑定的优先级

默认绑定 < 隐式绑定 < 显示绑定 < new 关键字绑定

箭头函数

简单了解一下箭头函数

箭头函数的构成:

  • ( ) : 参数
  • => : 箭头
  • { } : 函数的执行体
nums.forEach((item, index,arr) => {})

一些常见的简写:

  1. 如果参数只有一个,( ) 可以省略
num.forEach(item => {
    console.log(item)
})
  1. 如果函数执行体只有一行代码,那么 { } 也可以省略
num.forEach(item => console.log(item))
  1. 如果只有一行代码且这行代码返回一个对象
var foo = () => ({ a: 1, b: 2})

注:箭头函数不会绑定this、arguments属性,不能与new一起使用,会报错
就是说上面四种this绑定方法对箭头函数都不适用,箭头函数的this取决于上层作用域

箭头函数中this的指向

 var obj = {
    data: [],
    getData: function () {
    setTimeout(() => {
        var a = [1, 2, 3]
        this.data = a   // 此处的this指向obj
        }, 2000)
    }
}
obj.getData()

扩:settimeout和forEach中的this指向

 setTimeout(function () {
            console.log(this)
}, 1000)
// this 的指向是window
var foo = [1, 2, 3]
  foo.forEach(function (item) {
  console.log(item, this);
}, "a")
// forEach 中this的指向是第二个参数

Snipaste_2022-09-03_17-27-27.png

目录
相关文章
|
2月前
|
JavaScript 前端开发
javascript中的this
javascript中的this
|
2月前
|
JavaScript
JS中改变this指向的六种方法
JS中改变this指向的六种方法
|
17天前
|
自然语言处理 JavaScript 前端开发
在JavaScript中,this关键字的行为可能会因函数的调用方式而异
【6月更文挑战第15天】JavaScript的`this`根据调用方式变化:非严格模式下直接调用时指向全局对象(浏览器为window),严格模式下为undefined。作为对象方法时,`this`指对象本身。用`new`调用构造函数时,`this`指新实例。`call`,`apply`,`bind`可显式设定`this`值。箭头函数和绑定方法有助于管理复杂场景中的`this`行为。
40 3
|
7天前
|
JavaScript
js -- 函数总结篇,函数提升、动态参数、剩余参数、箭头函数、this指向......
js -- 函数总结篇,函数提升、动态参数、剩余参数、箭头函数、this指向......
|
2月前
|
JavaScript 前端开发
js中改变this指向、动态指定函数 this 值的方法
js中改变this指向、动态指定函数 this 值的方法
|
14天前
|
JavaScript 前端开发
JS中如何使用this方法
JS中如何使用this方法
|
2月前
|
自然语言处理 JavaScript 前端开发
在JavaScript中,this关键字的行为可能会因函数的调用方式而异
【5月更文挑战第9天】JavaScript中的`this`关键字行为取决于函数调用方式。在非严格模式下,直接调用函数时`this`指全局对象,严格模式下为`undefined`。作为对象方法调用时,`this`指向该对象。用`new`调用构造函数时,`this`指向新实例。通过`call`、`apply`、`bind`可手动设置`this`值。在回调和事件处理中,`this`可能不直观,箭头函数和绑定方法可帮助管理`this`的行为。
22 1
|
2月前
|
JavaScript 前端开发
深入探索JavaScript:如何改变this的指向
深入探索JavaScript:如何改变this的指向
14 2
|
2月前
|
JavaScript 前端开发
【专栏】`Function.prototype.apply` 在JavaScript中用于动态设定函数上下文(`this`)和参数列表
【4月更文挑战第29天】`Function.prototype.apply` 在JavaScript中用于动态设定函数上下文(`this`)和参数列表。它接受两个参数:上下文对象和参数数组。理解`apply`有助于深入JS运行机制。文章分三部分探讨其原理:基本概念和用法、工作原理详解、实际应用与注意事项。在应用中要注意性能、参数类型和兼容性问题。`apply`可用于动态改变上下文、传递参数数组,甚至模拟其他语言的调用方式。通过深入理解`apply`,能提升代码质量和效率。
|
2月前
|
JavaScript 前端开发 数据安全/隐私保护