call,apply,bind的区别

Javascript call,apply,bind的区别

call 和 apply 是为了改变 this 的指向
除了第一个参数外,call 可以接收一个参数列表,apply 只接受一个参数数组

1
2
3
4
5
6
7
8
9
10
11
12
let a = {
value: 'han'
}

function person(name, age) {
console.log(name)
console.log(age)
console.log(this.value)
}

person.call(a, 'han', 23) // han 23 handsome
person.apply(a, ['han', 23]) // han 23 handsome
1
2
3
4
5
6
let list = []
Array.apply(null, { length: 3 }).map((item, page) => {
page = page + 1
list.push({ code: page, name: `第${page}页` })
})

模拟实现 call

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Function.prototype.myCall = function(context) {
if (typeof this !== 'function') throw new Error('Error')
context = context || window
context.fn = this
let args = [...arguments].slice(1)
let result = context.fn(...args)
delete context.fn
return result
}

# context 为可选参数,如果不传的话默认上下文为 window
# 给 context 创建一个 fn 属性,并将值设置为需要调用的函数
# 因为 call 可以传入多个参数作为调用函数的参数,所以需要将参数剥离出来
# 然后调用函数并将对象上的函数删除

模拟实现 apply

1
2
3
4
5
6
7
8
9
10
11
12
13
Function.prototype.MyApply = function (context) { 
if (typeof this !== 'function') throw new TypeError('Error')
context = context || window
context.fn = this
let result
if (arguments[1]) {
result = context.fn(...arguments[1])
} else {
result = context.fn()
}
delete context.fn
return result
}

call 应用实例

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
46
47
48
49
50
51
52
53
54
55
56
/**
* @param obj
* @return {string}
*/
function dataType(obj) {
const str = Object.prototype.toString.call(obj)
return /^\[object (.*)\]$/.exec(str)[1].toLowerCase()
}

function isType(obj, type) {
return Object.prototype.toString.call(obj) === ('[object ' + type + ']')
}

function isString(obj) {
return isType(obj, 'String')
}

function isArray(obj) {
return isType(obj, 'Array')
}

function isObject(obj) {
return isType(obj, 'Object')
}

function isFunction(obj) {
return isType(obj, 'Function')
}

function isBoolean(obj) {
return isType(obj, 'Boolean')
}

function isNumber(obj) {
return isType(obj, 'Number')
}

function isUndefined(obj) {
return isType(obj, 'Undefined')
}

function isNull(obj) {
return isType(obj, 'Null')
}

function isDate(obj) {
return isType(obj, 'Date')
}

function isRegExp(obj) {
return isType(obj, 'RegExp')
}

function isMath(obj) {
return isType(obj, 'Math')
}

。。。待完善