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
}
}