✨了解下this和箭头函数的使用
✨调用位置
- 作用域跟在哪里定义有关,与在哪里执行无关
this指向跟在哪里定义无关,跟如何调用,通过什么样的形式调用有关this这个函数如何被调用(方便记忆)- 为了方便理解,默认情况下不开启严格模式
✨this的四种绑定规则
✨默认绑定
函数最常用的调用方式,调用函数的类型:独立函数调用
function bar() {
console.log(this) // window
}
✨隐式绑定
用最通俗的话表示就是:对象拥有某个方法,通过这个对象访问方法且直接调用
var obj = {
name: "xiao",
foo: foo
}
obj.foo() // obj对象
✨显示绑定 apply/call/bind(也称硬绑定)
但是在某些场景下,this的改变都是意想不到的,实际上我们无法控制回调函数的执行方式,因此没有办法控制调用位置已得到期望的绑定即this指向。
接下来的显示绑定就可以用来解决这一隐式丢失问题。
function foo() {
console.log("函数被调用了", this)
}
var obj = {
name: "obj"
}
foo.call(obj) //obj
foo.apply(obj) //obj
foo.apply("aaaa") //"aaaa"
call和apply的区别:
如果函数需要传入参数,call是直接传入参数,而apply是以数组形式传入参数
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.如果函数没有返回其他对象,表达式会返回这个新对象;
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的显示绑定高于隐式绑定
obj.foo.call("abc") //abc
obj.foo.apply("abc") //abc
- bind的显示绑定高于隐式绑定
function foo(){
console.log(this)
}
var obj = {
foo:foo.bind('aaa')
}
obj.foo() //'aaa'
- new关键字高于显示绑定(new不能和call/apply共用)
function foo(){
console.log(this)
}
var bar = foo.bind('aaa')
var obj = new bar() //foo()
✨箭头函数 (arrow function)
✨基本语法
首先箭头函数是ES6新增的语法
const foo = () => {}
✨箭头函数this
箭头函数中的this,永远指向外层作用域中最接近自己的普通函数的this
箭头函数的this指向该函数定义时所在的作用域
var name = "xiao"
var foo = () => {
console.log(this);
}
foo() //window
var obj = {foo: foo}
obj.foo() //window
foo.call("abc") //window
✨箭头函数的应用场景
箭头函数(因为箭头函数的this指向定义时的对象,即obj)
var obj = {
data: [],
getData: function() {
setTimeout(() => {
console.log(this)
}, 2000);
}
}
obj.getData()