function在javascript也是对象,对象的clone可以对基本类型数据赋值来clone,而要得到一个功能一样的function的副本,方式则不一样。

方法1

返回一个新的function,并在内部调用需要clone的函数

使用apply
1
2
3
4
5
6
7

function cloneFunction (f) {
return function (){
f.apply(this, arguments);
}
}

使用call
1
2
3
4
5
6
7

function cloneFunction (f) {
return function (){
f.call(this, ...arguments);
}
}

方法2

使用bind

Function.prototype.bind会返回一个新的function,也可以用来克隆函数

使用bindbind
1
2
3
4
5

function cloneFunction (f, context) {
return f.bind(context || {});
}

bind会绑定函数的上下文,所以函作为方法调用时可能会不方便

举个栗子

对比
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

function f(){
console.log("this:", this);
console.log("name:",(this && this.name));
}

function cloneFunction (f){
return function () {
f.apply(this, arguments);
}
}

function clone(f, context){
return f.bind(context || {});
}

let julien = {
name: "julien",
print: cloneFunction(f)
}

let jack = {
name: "jack",
print: clone(f)
}

jack.print()

// this: {}
// name: undefined

julien.print()

// this: { name: 'julien', print: [Function] }
// name: julien

可以发现使用bind的this是绑定的,而使用apply时this是运行时才确定的