call
//call
Function.prototype.mycall = function(){
// 记录函数this的指向
var target = arguments[0] || window;
// 获取传递的参数
var _args = Array.from(arguments).slice(1);
// 执行函数 this --> test
// 在target添加一个属性 - test
target.fn = this;
target.fn(..._args);
// 删除掉target上的fn属性
delete target.fn;
}
apply
// apply
Function.prototype.myApply = function(){
// 记录函数this的指向
var target = arguments[0] || window;
// 获取传递的参数
var _args = arguments[1];
// 执行函数 this --> test
// 在target添加一个属性 - test
target.fn = this;
target.fn(..._args);
// 删除掉target上的fn属性
delete target.fn;
}
bind
// bind
Function.prototype.myBind = function(){
// 记录函数this的指向
var target = arguments[0] || window;
// 获取传递的参数
var _args = Array.from(arguments).slice(1);
// 记录调用bind的函数 test
var that = this;
// 返回一个新函数
return function(){
// 最终执行的还是test 将test的this指向进行改变 并且记录剩余的参数
// 执行函数
// 判断当前这个函数时如何被调用的 如果是new 调用 直接按照new步骤执行
// new.target : 1. 函数体 2. undefined
if(!new.target){
var arg = Array.from(arguments);
// 拼接参数
arg = _args.concat(arg);
target.fn = that;
target.fn(...arg);
delete target.fn;
}else{
return new that();
}
}
}
function test(){
console.log(this);
}
var obj = {
d:111
}
// var newTest1 = test.myBind(obj,1,2);
// var obj = new newTest1();
// 内置的bind方法
var newTest = test.bind(obj,1,2);
newTest();
var obj = new newTest(); // {}
// console.log(obj); // {} {d:111}
// 如何知道函数是不是被new调用的 new.target
// new 关键字
/*
1. 在函数内部创建一个空对象
2. 将this指向这个空对象,对象的隐式原型指向构造函数的原型
3. 逐行执行函数中的代码
4. 隐式返回对象
*/