一.Function.prototype.call()
语法:
function.call(thisArg, arg1, arg2, ...)
实现功能:
改变调用者function的this指向,指向call的第一个参数,并且接收剩余参数,同时调用function
call的源码
主要用到了arguments接收实参和 "... ” ---展开符传参
Function.prototype.mycall = function() {
/*
用arguments接收实参
传入的参数为真值就返回这个参数,为null/undefind/其他假值 则指向window
短路运算
*/
var paramFirst = arguments[0] || window;
/*
接收剩余参数
将伪数组aruments转换成真数组,调用数组方法,切割数组,得到剩余参数
*/
var _arg = Array.from(arguments).slice(1);
//this指向调用者,如下面实例,指向demo
paramFirst.fn = this;
//调用这个函数即demo函数体
paramFirst.fn(..._arg);//...是es6中的展开语法,将数组中的值依次传入
/*
删除paramFirst中添加的fn,
是为了让paramFirst本身不产生额外的fn,
外层也调用不了fn,以免产生多余的影响
*/
delete paramFirst.fn
}
function demo(a,b) {
console.log(this);
console.log(a+b)
}
var obj = {
name: "张三",
age: 18
}
demo.mycall(obj, 1, 2);
二.Function.prototype.apply()
语法:
func.apply(thisArg, [argsArray])
实现功能:
改变调用者function的this指向,指向aplly的第一个参数,并且接收剩余参数,同时调用function
与call的唯一不同就是,剩余参数是以数组形式传递
apply的源码
主要用到了arguments接收实参,具体代码和call大同小异
Function.prototype.myApply = function() {
var target = arguments[0] || window;
var _arg = arguments[1];
target.fn = this;
target.fn(..._arg);
delete target.fn
}
function demo(a,b) {
console.log(this);
console.log(a+b)
}
var obj = {
name: "张三",
age: 18
}
demo.myApply(obj, [1, 2]);
三.Function.prototype.bind()
语法:
function.bind(thisArg[,arg1[,arg2,arg3]]
实现功能:
改变调用者function的this指向,指向bind的第一个参数,并且接收剩余参数.
并返回一个新的函数,新函数接收调用者的所有剩余参数
bind的源码
主要用到了arguments接收实参,和数组concat()方法,slice()方法。
并且考虑到了调用者如果是new 构造函数的特殊情况,因为new会改变this指向。
Function.prototype.mybind = function() {
var param1 = arguments[0] || window;
var that = this
var _arg = Array.from(arguments).slice(1);
//返回一个新函数
return function() {
var array = _arg.concat(Array.from(arguments));
//用new.target判断调用者是否为new 构造函数的对象
if (!new.target) {
param1.fn = that;
param1.fn(...array);
delete param1.fn;
} else {
return new that(...array);
}
}
}
function Person(name) {
this.name = name
}
var obj = new Person("张三");
function add(a, b) {
console.log(this)
console.log(a + b)
}
//bind三种传参情况
add.mybind(obj, 1, 2)()
add.mybind(obj, 1)(2)
add.mybind(obj)(1, 2);
这个记录下来为了方便以后使用的方便,也希望大佬们多多交流,多多留言,指出我的不足的之处啦!
有需要的小伙伴可以研究研究啦!!