this
- 前言
- 一、this是什么?
- 二、做什么?
-
- 1.全局环境
- 2.函数环境
- 3.new实例对象
- 4.apply、bind、call绑定
-
- [4.1 apply()](#4.1 apply())
- [4.2 call()](#4.2 call())
- [4.3 bind()](#4.3 bind())
- 三、为什么用this?
- 四、如何改变this?
- 五、应用场景?
- 总结
前言
痛点
经常写Vue项目,现在自己问题是只知道如何使用,但是不知道为什么用它。Vue2通过它获取Vue实例上的属性,而Vue3写法基本上抛弃它了。为什么抛弃它呢?
一、this是什么?
先看几段代码
可以看出在不同地方调用,this的值是不一样的。简单来说,它就是用来指向某个对象的。
官方术语
在JavaScript中,this是一个特殊的关键字,用于引用当前执行代码的上下文对象,它的具体值取决于代码在何处被调用和如何被调用
二、做什么?
从上面知道,this的值是一个对象,它的值取决于代码在哪里调用。那么调用的环境有哪些?他们的值又会发生什么样的变化?
1.全局环境
当在全局作用域中使用this时,它引用的是全局对象(在浏览器中是window对象)。
2.函数环境
当在函数中使用this时,它引用的是调用该函数的对象。如果函数是通过一个对象的方法调用的,this将引用该对象。如果函数是独立调用的(即不是作为对象的方法),
最外层调用函数时,this指向window
javascript
function testA(){
console.log(this)
}
testA()
通过对象调用函数,指向对象
javascript
let obj = {
name:'55',
testA: function() {
console.log(this)
}
}
console.log(obj.testA())
3.new实例对象
javascript
function testA() {
console.log(this)
}
let test = new testA();
console.log(test)
4.apply、bind、call绑定
它们的第一个参数就表示改变后的调用这个函数的对象。因此,这时this指的就是这第一个参数
4.1 apply()
javascript
var month = 2;
var day = 6;
function testA(month,day) {
console.log(this.month,this.day) //3 7
}
let obj = {
month:3,
day:7
}
testA.apply(obj)
4.2 call()
javascript
var month = 2;
var day = 6;
function testA(month,day) {
console.log(this.month,this.day)//3,7
}
let obj = {
month:3,
day:7
}
testA.call(obj)
4.3 bind()
javascript
var month = 2;
var day = 6;
function testA(month, day) {
console.log(this.month, this.day) //3 7
}
let obj = {
month: 3,
day: 7
}
let s = testA.bind(obj)
s(1, 9)
三、为什么用this?
- 语法简洁
- 动态改变代码的上下文对象
- this 没有作用域的限制,嵌套的函数不会从调用它的函数中继承 this
四、如何改变this?
- 箭头函数(定义时确定,并以后不改变值,即使bind,call也不行)
- 缓存this
- apply、call 、 bind
- new 实例化一个对象
五、应用场景?
- 普通函数调用
- 普通调用
- 对象调用函数
- 构造函数(new)
- apply、bind、call
- 箭头函数调用
- 箭头函数和普通函数区别
- 箭头函数不会创建自己的this(定义时捕获外层执行环境的this,并继承这个this值,之后不会改变)
- 箭头函数继承而来的this指向永远不变
- apply、bind、call无法改变箭头函数中this的指向(定义时就已经确定且永远不会改变)
- 箭头函数不能作为构造函数使用 (箭头函数没有自己的this)
new
JS内部首先会先生成一个对象;
再把函数中的this指向该对象;(箭头函数没有自己的this)
然后执行构造函数中的语句;
最终返回该对象实例。 - 箭头函数没有自己的arguments(在箭头函数中访问arguments实际上获得的是外层函数执行环境中的值)
- 箭头函数没有原型prototype
- 箭头函数不能用作Generator函数,不能使用yeild关键字
总结
- 4种绑定(默认,隐式,显式,new) 优先级 低-高
- 箭头函数没有自己的this,因为箭头函数定义时捕获上下文对象,并将this赋值,此后什么方法都不能改变this的值。不能构造函数(new实例对象的过程中会将函数this赋值给实例对象,但是箭头函数无自己的this)
- apply、call、bind 第一个参数是this指向
- apply和call用法一样,apply传参时数组,call是指定参数,它们立即执行
- bind 需要创建对象接收,并且还可以再次传递参数,但只在第一次生效