第二部分基础知识(this,call,apply,bind知识点精讲)
我相信,在大多数的JavaScript初学者中,都或多或少的对this的指向感到迷惑。对Function.prototype.call,Function.prototype.apply和Function.prototype.bind这三个方法的应用也有些生疏。我们有必要在学习设计模式之前先理解这几个概念
1.1 this
和别的语言大相径庭的是,Javascript的this总是指向一个对象,而具体指向哪个对象是在函数运行时基于函数的执行动态环境绑定的,而非函数声明时的环境
1.1.1 this的指向
在实际的应用中,我们大致可以把this的指向分为以下四种情况
作为对象的方法调用,this指向这个对象本身
let obj = {
a:1,
getA:function() {
console.log(this)
console.log(this.a)
}
}
obj.getA() //true 1
作为普通函数直接调用,此时得this指向全局对象,在浏览器环境中全局对象为window,在node环境中,全局对象为global
window.a = 1
function test() {
console.log(this)
console.log(this.a)
}
test() //window 1
构造函数中得this,指向他的实例对象
function Person(name,age) {
this.name = name
this.age = age
}
Person.prototype.setName = function(newName) {
console.log(this)
console.log(this.name)
this.name = newName
}
let jack = new Person("jack",18)
jack.setName("rose") //{name:"jack",age:18} "jack"
和普通函数调用相比,通过Function.prototype.call,Function.prototype.apply,和Function.prototype.bind调用函数,可以动态得改变传入函数得this
window.a = 1
let obj = {
a:2,
}
function getA() {
console.log(this)
console.log(this.a)
}
getA.apply(obj) // obj ,2
通过上述代码我们可以直观得发现,apply函数可以动态修改函数getA函数中得this指向,将this得指向从全局对象修改成了obj对象。其实,apply,call,bind三者都可以用来修改this得指向,那么他们之间到底有什么区别呢,下面就来跟我一起继续探索吧
var func = function(a,b,c) {
alert([a,b,c]) //输出[1,2,3]
}
func.call(null,1,2,3)
func.apply(null,[1,2,3])
var bindFn = func.bind(null,1,2,3)
bindFn()
通过上述代码,我们可以发现,call和apply二者的区别在于传参形式上的不同,bind和前两者最大的区别在于,bind会返回一个改变this指向的新函数
下面,我们就来看几个实际开发中的真实场景,来加深一下我们对this,appy,call,bind的理解,以及他们的实际用途
在实际开发中,我们经常会遇到一些类数组,类数组虽然拥有一些数组的特性,但是它并不能使用数组的方法。例如,函数的参数列表arguments就是一个类数组,有时,我们希望往arguments添加一个元素,这时候,我们就可以采用这种巧妙的方式达到目的
Array.prototype.push.call(arguments,3)
好了,今天的分享就到这里吧,我们下次再见~~