function.call(thisArg, arg1, arg2, ...)
参数
thisArg是function运行时this的值
arg1,arg2指定的参数列表
返回值
- 该function的返回值,如果无返回值则是undefined
用途
-
调用父构造函数
function Product(name, price) { this.name = name; this.price = price; } function Food(name, price) { Product.call(this, name, price); this.category = 'food'; } //food console.log(new Food('cheese', 5).category); //cheese console.log(new Food('cheese', 5).name);
-
调用匿名方法
var btns = document.getElementsByTagName("button") function fun(){ for(var i =0;i<btns.length;i++){ ( function (value){ btns[value].onclick= function(){ console.log(value) } } ).call(this,i) } } fun()
-
改变this指向
var a = 1; var o = { a: 2 } function b() { console.log(this.a); } b(); // 1 b.call(o); // 2
实现
Function.prototype.mycall = function(thisArg,...args){
//this如果为空,指向window
let context = thisArg===null?window:Object(thisArg)
let fn =Symbol()
//避免属性冲突或者被外部修改
context[fn] = this//获取方法
let result;
if(args) {
result = context[fn](...args);
} else {
result = context[fn]();
}
// 4. 清掉挂载的 fn,并返回
delete context[fn];
return result;
}
func.apply(thisArg, [argsArray])
apply和call的区别就是接受的参数不一样
apply接受一个参数数组,call接受参数列表
Function.prototype.myApply = function(thisArg,args){
//this如果为空,指向window
let context = thisArg===null?window:Object(thisArg)
if (!Array.isArray(args)) {
throw new TypeError('args is not a Array');
}
let fn =Symbol()
//避免属性冲突或者被外部修改
context[fn] = this//获取方法
let result;
if(args) {
result = context[fn](...args);
} else {
result = context[fn]();
}
// 4. 清掉挂载的 fn,并返回
delete context[fn];
return result;
}
function.bind(thisArg[, arg1[, arg2[, ...]]])
参数
- thisArg
调用绑定函数时作为 this
参数传递给目标函数的值。 如果使用new
运算符构造绑定函数,则忽略该值。当使用 bind
在 setTimeout
中创建一个函数(作为回调提供)时,作为 thisArg
传递的任何原始值都将转换为 object
。如果 bind
函数的参数列表为空,执行作用域的 this
将被视为新函数的 thisArg
。
- arg1,arg2指定的参数列表
返回值
function.bind(thisArg[, arg1[, arg2[, ...]]])
用途
bind 就是返回一个原函数的拷贝,并拥有指定的 this 值和初始参数,不可以更改箭头函数。
实现
Function.prototype.mybind= function(thisArg,...args){
let context = thisArg===null?window:Object(thisArg)
let fn = Symbol(); // 避免属性冲突或被外部修改
let _this = this
let resultFn = function(...newArgs){
let resultContext;
//依据定义如果是new则this指向原构造函数
if(!new.target){
resultContext = context
}else{
resultContext = this
}
resultContext[fn] = _this
let result = resultContext[fn](...[...args,...newArgs])
delete resultContext[fn]
return result;
}
//3. 拷贝原函数的 prototype,防止外部修改影响原函数
if (this.prototype) {
resultFn.prototype = Object.create(this.prototype);
}
return resultFn;
}