apply 和 call 都是为了解决改变 this 的指向。作用都是相同的,只是传参的方式不同。
第一个参数都是改变this的指向,apply 接收一个数组作为参数,call 接收一个参数列表。
而bind 则返回一个函数。
let obj = {
value: 1
}
function getValue(name, age){
console.log(name, age, this.value)
}
getValue.apply(obj, ['zhangsan', '18']) // zhangsan 18 1
getValue.call(obj, 'lisi', '20') // lisi 20 1
getValue.bind(obj, 'wangwu', '20')() // wangwu 20 1
getValue.bind(obj)('wangwu', '20') // wangwu 20 1
//使用apply实现二维数组降维
[].concat.apply([], [1,2,[3,4,5],[6,7]])
//使用call将参数列表转为数组
function fn(){return [].slice.call(arguments)}
function fn(...args){return arg}
//一个通用的事件绑定函数,call实现代理
function bindEvent(elem, type, selector, fn) {
if (fn == null) {
fn = selector
selector = null
}
elem.addEventListener(type, function (e) {
var target
if (selector) {
target = e.target
if (target.matches(selector)) {
//改变指向到目标元素
fn.call(target, e)
}
} else {
fn(e)
}
})
}
//使用代理
var div1 = document.getElementById('div')
bindEvent(div1, 'click', 'a.class', function (e) {
console.log(this.innerHTML)
})
//兼容IE8的写法
var addEvent = (function() {
if(window.addEventListener) {
return function(el, type, fn, capture) {
el.addEventListener(type, function(e) {
fn.call(el, e);
}, capture);
}
}else {
return function(ele, type, fn) {
el.attachEvent('on' + type, function(e) {
fn.call(el, e);
})
}
}
})()
如何实现一个apply函数
Function.prototype.myApply = function(context){
context = context || window
context.foo = this;
//判断第二个参数是否存在且是数组
let result = arguments[1] ?
( Array.isArray(arguments[1]) ?
context.foo(...arguments[1]) : context.foo(arguments[1]))
: context.foo()
delete context.foo
return result
}
如何实现一个call函数
Function.prototype.myCall = function(context){
context = context || window
// 第一个参数为函数的执行上下文,就把函数赋值给foo
context.foo = this;
//将剩余参数取出
let args = [...arguments].slice(1);
let result = context.foo(...args);
// 执行完毕需要删除foo属性
delete context.foo;
return result;
}
如何实现一个bind函数
Function.prototype.myCall = function(context){
context = context || window
let _this = this;
let args = [...arguments].slice(1);
return fcuntion(){
_this.apply(context, args.concat(...arguments))
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。