[](()call,apply,bind都是用于改变this指向的
区别:
传参不同
[](()call用逗号分隔的形式传参
函数名.call(目标对象,参数1,参数2,…参数n)
例如:getName.call(obj,‘王五’,25,‘北京’)
[](()apply参数用数组的形式传递
函数名.apply(目标对象,[参数1,参数2,…参数n])
例如:getName.apply(obj,[‘王五11’,25,‘上海’])
[](()bind用逗号形式传参
getName.bind 《大厂前端面试题解析+Web核心总结学习笔记+企业项目实战源码+最新高清讲解视频》无偿开源 徽信搜索公众号【编程进阶路】 (obj,‘王五11’,25,‘上海’)() 或 getName.bind(obj)(‘王五11’,25,‘上海’)
函数是否被执行
[](()cal和apply是直接调用函数
[](()bind是返回函数本身,如果要执行,必须再后面再加()调用
[](()getName.bind(obj)()
[](()call,apply实现原理
[](()call的实现原理(不用call,自己手动模拟实现一个call的功能)
call是基于函数实现的
给作用的目标对象添加一个临时函数,处理赋值操作
接收参数处理
最后再删除这个临时函数
实例化对象=new 构造函数() //其中构造函数也称为类,一个类可以生成多个实例化对象
var f1=new Function() // 其中的构造函数中this===f1 永远相等
var p1=new Person() //其中的构造函数中this===p1 永远相等
//call模拟实现原理代码:
Function.prototype.call2 = function (context) {
//目标对象
context = context || window;
//this===实例化的函数,函数本质上也是对象
//给context添加一个临时函数
context.fn = this;
//接收参数处理 arguments
console.log(‘arguments:’,arguments)
var args = [];
for (var i = 1; i < arguments.length; i++) {
// [“arguments[0]”, “arguments[1]”, “arguments[2]”]
args.push(‘arguments[’+i+‘]’)
// args.push(arguments[i])
}
//传参执行context.fn()函数
eval(‘context.fn(’ + args + ‘)’)
//删除临时函数
delete context.fn
}
[](()apply实现原理
Function.prototype.apply2 = function (context,arr) {
//目标对象
context = context || window;
//this===实例化的函数,函数本质上也是对象
//给context添加一个临时函数
context.fn = this;
if (!arr) {
context.fn()
} else {
//接收参数处理 arguments
var args = [];
for (var i = 0; i < arr.length; i++) {
// [“arguments[0]”, “arguments[1]”, “arguments[2]”]
args.push(‘arr[’+i+‘]’)
// args.push(arguments[i])
}
//传参执行context.fn()函数
eval(‘context.fn(’ + args + ‘)’)
}
//删除临时函数
delete context.fn
}
[](()bind实现原理
var obj = {
init: 1,
add: function(a, b) {
return a + b + this.init;
}
}
obj.add(1, 2); // 4
var plus = obj.add;
plus(3, 4); // NaN,因为 this.init 不存在,这里的 this 指向 window/global
plus.call(obj, 3, 4) // 8
plus.apply(obj, [3, 4]); // 8, apply 和 call 的区别就是第二个参数为数组
plus.bind(obj, 3, 4); // 返回一个函数,这里就是 bind 和 call/apply 的区别之一,bind 的时候不会立即执行