飞雪连天射白鹿,笑书神侠倚碧鸳

0%

必知必会的bind-call-apply

this是运行时才确定,用来改变this的指向
执行函数并绑定参数

之前一篇文章通过数组边遍历边删除来回顾迭代器附录中描述了一遍this与箭头函数的几种情况

当this是null、undefined时,默认指向window
箭头函数无arguments 对象,用 Rest 参数代替

简述

call(‘绑定this’,’参数’,’列表’) 立即调用
apply(‘绑定this’,[‘参数’,’数组’]) 立即调用
bind(‘绑定this’,’参数’,’列表’) 返回函数需要再次调用

应用场景

1
2
3
4
5
6
7
8
9
10
11
12
13
// 调用其他函数并传入参数
var obj = {
message: 'hello: '
}
function getName(str1, str2) {
console.log(this.message + str1 + ' ' + str2)
}
getName.call(obj, 'a', 'b') // this指向了obj
getName.apply(obj, ['a', 'b']) // hello : a b

var arr = [1, 2, 3, 89, 46]
var max = Math.max.call(null,arr[0],arr[1],arr[2])// 89
var max = Math.max.apply(null,arr)//89 合理使用apply处理
1
2
3
4
5
6
7
8
9
10
11
12
// 将类数组转化为数组
var trueArr = Array.prototype.slice.call(arrayLike);
// 数组arr1更新合并
var total = [].push.apply(arr1, arr2);
// 类型判断
Object.prototype.toString.call(obj)
// 代理 console.log
function log(){
console.log.apply(console, arguments);
}
//
var log = console.log()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 继承
var Person1 = function(){
this.name = 'Dot';
}
var Person2 = function(){
this.getname = function(){
console.log(this.name);
}
// 使用Person1对象代替this,使Person2中继承Person1的属性和方法
Person1.call(this);
}
var Person3 = function(){
Person1.apply(this,arguments)//将父元素所有方法在这里执行一遍就继承了
}
var person = new Person2();
person.getname();
1
2
3
4
5
6
7
8
9
10
11
// 函数珂里化
var add = function(x) {
return function(y) {
return x + y;
};
};

var increment = add(1); // 保存x=1
var addTen = add(10); // 保存x=10
increment(2);// 3 1+2
addTen(2);// 12 10+2
1
2
3
4
5
6
7
8
9
10
11
// 实现bind
if (!Function.prototype.bind) {
Function.prototype.bind = function () {
var self = this, // 保存原函数
context = [].shift.call(arguments), // 保存需要绑定的this上下文
args = [].slice.call(arguments); // 剩余的参数转为数组
return function () { // 返回一个新函数
self.apply(context, [].concat.call(args, [].slice.call(arguments)));
}
}
}

文章题目也不好取啊- -想起之前有本工具手册《MySQL必知必会》,那就用你好了


附录1 this

我们再来看看this的更多例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
function a1(){
console.log(this) // window
}
var obj = {
a1:()=>{
console.log(this) // window
},
a2:function(){
console.log(this) // obj
},
a3:function(){
console.log(this)
}
}
obj.a1() // => obj.a1.call(undefined) 默认绑定window
obj.a2() // => obj.a2.call(obj)
var obja3 = obj.a3;
obja3() // => obj 绑定为window了

id.addEventListener('click',function(){
console.log(this) // 指向绑定的id元素
})

// 这里说一下setTimeout异步函数
// 当callback是普通函数时this是window,丢失this
// 当callback是箭头函数时this是绑定了当前所在作用域的this
setTimeout(function(){
console.log(this);
}, 200);

// 构造函数
function Person(name,age){
// 这里的this都指向实例
this.name = name
this.age = age
// 箭头函数也一样
this.getAge = () =>{
console.log(this.age)
}
this.getAge = function(){
console.log(this.age)
}
}
var p = new Person('P',2)
p.getAge()//2

附录2 函数执行时说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
obj1.fn() 
obj1.fn.call(obj1);

fn1()
fn1.call(null)

f1(f2)
f1.call(null,f2)


obj1.fn()
obj1.fn.apply(obj1);

fn1()
fn1.apply(null)

f1(f2)
f1.apply(null,f2)
听说,打赏我的人最后都找到了真爱
↘ 此处应有打赏 ↙
// 用户脚本