在说call,apply和bind之前先说说this
在ES6之前并没有箭头函数,this是我们很头疼的一件事,我也发现很多老程序员对this的指向判断也不是很准确,由于有了箭头函数,所以在工作中我一般都是用箭头函数,很少使用普通函数,但是在很多面试题中经常有this的一些题目
this
this是动态的,只有在函数调用的时候才能确认下来,和在哪调用的也没有关系。所以我们判断this的指向根据以下两点
1)this是属于哪个函数的
2)这个函数是如何被调用的
简单的说this就是谁调用我我就指向谁,那么根据函数的四种调用模式来判断this的指向
1、函数调用模式(ps:fn();this指向window)
var name = "windowsName"
function fn() {
let name = 'fnName'
console.log(this.name)
}
fn()
// windowsName
结果是windowsName,为什么呢?因为fn()在全局作用域中,fn()相当于window.fn()所以结果是windowsName,那么我们再做一题
var name = "windowsName"
function fn() {
let name = 'fnName'
innerFunciton()
function innerFunciton() {
console.log(this.name)
}
}
fn()
// windowsName
2、方法调用模式(对象名.函数名())
var name = "windowsName"
var a = {
name: "fnName",
fn : function () {
console.log(this.name);
}
}
let f = a.fn
f()
// windowsName
结果很意外是windowsName,为什么呢?我们看一下最后的f()是什么?是函数对象a里面的fn函数,那是谁调用了f(),f()在全局中,所以很显然是windows,所以结果就是windowsName,再看一题
var name = "windowsName"
var a = {
name: "fnName",
fn : function () {
console.log(this.name);
}
}
a.fn()
// fnName
这里就是fnName,我们看是谁调用了fn()? 是对象a,所以this指向a
var name = "windowsName"
function func1() {
console.log(this.name)
}
var a = {
name: "Cherry",
func1: function() {
console.log(this.name)
},
func2: function() {
this.func1()
setTimeout(function () {
this.func1()
}, 100);
}
}
a.func2()
// Cherry
// windowsName
3、构造函数模式;(new 构造函数();this指向新创建出来的实例)
这里不多做解释
4、上下文模式:方法借用模式call apply bind
任何函数都可以调用这三个方法先说一下call
比如说xiaoming(小明)有一个方法叫liaomei(撩妹),那么xiaowang(小王)并没有这个方法,那怎么办呢?这里就可以用call借用,
xiaoming.liaomei.call(xiaowang,liaomei的参数)
参数:没有参数或者第一个参数为null,函数内的this指向window;一个:指向这个对象,可以改变this;多个:除了第一个其他作为函数的实际参数
apply(和call的方法是一样的,区别在与参数)apply的第二个参数是一个数组
bind创建一个新的函数,并且返回,新函数和fn函数是一模一样的,新函数内的this指向被固定了,固定成了bind的参数,注意点:bind是不会调用fn函数