了解下this和箭头函数的使用

✨调用位置

  • 作用域跟在哪里定义有关,与在哪里执行无关
  • this指向跟在哪里定义无关,跟如何调用,通过什么样的形式调用有关
  • this(这个) 这个函数如何被调用(方便记忆)
  • 为了方便理解,默认情况下不开启严格模式

✨this的四种绑定规则

✨默认绑定

函数最常用的调用方式,调用函数的类型:独立函数调用

1
2
3
function bar() {
console.log(this) // window
}

✨隐式绑定

用最通俗的话表示就是:对象拥有某个方法,通过这个对象访问方法且直接调用

1
2
3
4
5
6
var obj = {
name: "xiao",
foo: foo
}

obj.foo() // obj对象

✨显示绑定 apply/call/bind(也称硬绑定)

但是在某些场景下,this的改变都是意想不到的,实际上我们无法控制回调函数的执行方式,因此没有办法控制调用位置已得到期望的绑定即this指向。

接下来的显示绑定就可以用来解决这一隐式丢失问题。

1
2
3
4
5
6
7
8
9
10
11
function foo() {
console.log("函数被调用了", this)
}

var obj = {
name: "obj"
}

foo.call(obj) //obj
foo.apply(obj) //obj
foo.apply("aaaa") //"aaaa"

callapply的区别:

如果函数需要传入参数,call是直接传入参数,而apply是以数组形式传入参数

1
2
3
4
5
6
function sum(num1, num2, num3) {
console.log(num1 + num2 + num3, this)
}

sum.call("call", 20, 30, 40)
sum.apply("apply", [20, 30, 40])

✨new绑定

JavaScript中的函数可以当做一个类的构造函数来使用,也就是使用new关键字

我们通过一个new关键字调用一个函数时(构造器), 这个时候this是在调用这个构造器时创建出来的对象

使用new关键字来调用函数时,会执行如下的操作:

1.创建一个全新的对象;

2.这个新对象会被执行prototype连接;

3.这个新对象会绑定到函数调用的this上(this的绑定在这个步骤完成);

4.如果函数没有返回其他对象,表达式会返回这个新对象;

1
2
3
4
5
6
7
8
9
10
function Person(name, age) {
this.name = name
this.age = age
}

var p1 = new Person("xiao", 18)
console.log(p1.name, p1.age) //xiao 18

var p2 = new Person("ran", 30)
console.log(p2.name, p2.age) //ran 30

✨this的优先级 从高到低

总结:new绑定 > 显示绑定(call/apply/bind)>隐式绑定(obj.foo())> 默认绑定(foo())

  • 默认绑定优先级最低
  • call/apply的显示绑定高于隐式绑定
1
2
obj.foo.call("abc")     //abc 
obj.foo.apply("abc") //abc
  • bind的显示绑定高于隐式绑定
1
2
3
4
5
6
7
8
9
function foo(){
console.log(this)
}

var obj = {
foo:foo.bind('aaa')
}

obj.foo() //'aaa'
  • new关键字高于显示绑定(new不能和call/apply共用)
    1
    2
    3
    4
    5
    6
    function foo(){
    console.log(this)
    }
    var bar = foo.bind('aaa')

    var obj = new bar() //foo()

✨箭头函数 (arrow function)

✨基本语法

首先箭头函数是ES6新增的语法

1
const foo = () => {}

✨箭头函数this

箭头函数中的this,永远指向外层作用域中最接近自己的普通函数的this

箭头函数的this指向该函数定义时所在的作用域

1
2
3
4
5
6
7
8
9
10
11
var name = "xiao"

var foo = () => {
console.log(this);
}

foo() //window

var obj = {foo: foo}
obj.foo() //window
foo.call("abc") //window

✨箭头函数的应用场景

箭头函数(因为箭头函数的this指向定义时的对象,即obj

1
2
3
4
5
6
7
8
9
10
var obj = {
data: [],
getData: function() {
setTimeout(() => {
console.log(this)
}, 2000);
}
}

obj.getData()