1. apply的原理的实现
Function.prototype.myapply = function (context) {
context = context || window; // 当前上下文指向函数或者window
context.fn = this; // 给当前添加属性fn,并且该属性为调用的函数,那么this就是指向当前的调用函数
let resurlt;
// 判断存储是否有第二个参数,如果有第二个参数就将其展开
if (arguments[1]) { // 判断apply是否有参数(第二个参数)
resurlt = context.fn(...arguments[1])
} else {
resurlt = context.fn()
}
delete context.fn; // 删除原型链上的fn属性
return resurlt;
}
let name = 'ys';
let age = '18';
let obj = {
name: 'xiaoli',
myF: function (name, age) {
console.log(this)
console.log(name + '---' + age)
}
}
let myobj = [12, 78]
obj.myF(1, 2) // {name: "xiaoli", myF: ƒ} this指向obj
obj.myF.myapply(this,myobj) // this指向window
2. call的原理的实现
Function.prototype.mycall = function(context){
context = context || window; // 当前上下文的指向
context.fn = this; // 给context创建一个fn属性,并且该属性为调用的函数
const args = [...arguments].slice(1);// 传入的参数
const resurlt = context.fn(...args); // 给调用的函数传参
delete context.fn; // 删除对象上的函数
return resurlt; // 返回调用函数
}
3.bind的原理的实现
Function.prototype.mybind = function(context) {
if(typeof this !== 'function'){ // 判断是否是函数,不是抛出异常
throw new TypeError('error')
}
var args = arguments.slice(1); // 获取参数
var _this = this;
return function F() {
if(this instanceof F){ // this 是F的实例化对象,直接返回new 一个对象
return new _this(args,...arguments)
}
return _this.apply(context,args.concat(...arguments)) // 这个是this不指向指定函数,所以需要apply绑定修改this
}
}