apply和call的用法

###1.基本用法

call和apply这两个方法在利用的时候一般是用来修改函数调用时候的this指向的。比如我们看下面的这个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="test"></div>
</body>
<script>
//var getId = document.getElementById;
var getId = function(id){
return document.getElementById(id);
}
getId('test');
</script>
</html>

这里是可以得到id为test的标签的,但是如果将getID换成注释中的那句话的时候,这时候在大多数浏览器中就会报错。这是因为如果在很多浏览器里面,getElementById这个方法内部实现需要this,这个this应该是指向document。当getElementById作为document的属性被调用的时候,方法内部的this确实是指向document的。但如果getId引用了document.getElementById之后,再去调用函数的话,就成了普通的函数调用,函数里面的this就指向了windows而不是document。

我们可以利用apply来实现这个调用的过程:

1
2
3
4
5
6
7
document.getElementById = (function(func){
return function(){
return func.apply(document,arguments)
}
})(document.getElementById)
var getId = document.getElementById;
getId('test');

这时候利用apply这个函数,将this所指向的对象指向了document,就能够实现原来的功能了。

利用apply和call可以修正我们函数的this,比如下面这个例子:

1
2
3
4
5
6
7
document.getElementById('test').onclick = function(func){
console.log(this.id);
var func = function(){
console.log(this)
}
func()
}

在这个例子中,外层的console.log能够正常输出test,但是内部函数输出的却是undefined,这时候如果还想让内部的函数像外部的函数一样正常输出的话,就需要利用apply来调用函数。

1
2
3
4
5
6
7
document.getElementById('test').onclick = function(func){
console.log(this.id);
var func = function(){
console.log(this)
}
func.call(this)
}

###2.利用Function.prototype.bind来指定函数内部的this

大部分的浏览器都实现了Function.prototype.bind这个函数用来指定Function的this指向。下面的这个例子用来模拟这个过程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Function.prototype.bind = function(context){
var self = this;
return function(){
return self.apply(context,arguments);
}
}

var obj = {
name:"Jone"
}

var func = function(){
console.log(this.name)
}.bind(obj);
func(obj)

在定义Function.prototype.bind的时候,context就是我们想要修正的this对象。在函数体内,首先我们先用一个self对象将函数的引用保存起来,之后返回一个函数,这个函数就是在我们调用func()的时候被执行的。在函数的内部,self.apply才是执行原来的func函数,并且指定了context是这个函数的this。

3.借用其他对象的方法

0%