call方法
/**
* 实现一个caLl方法
*/
Function.prototype.mycall = function(context) {
//判断是否传入指定的对象
context = context || window;
//拿到传入的参数
let args = [...arguments].slice(1);
//把调用的函数添加到对象中
context.fn = this;
//执行函数
let result = context.fn(...args);
//执行函数后,从对象中删除掉函数
delete context.fn;
return result;
}
function Test() {
console.log(this.name);
console.log(this.sex);
}
let obj = {
name: '李四',
sex: '男'
}
Test.mycall(obj)
执行结果
李四
男
apply方法
/**
* 实现apply方法
* 大体实现方法和apply相同
*/
Function.prototype.myapply = function(context) {
context = context || window;
context.fn = this;
let result;
if (arguments[1]) {
result = context.fn(...arguments[1]);
} else {
result = context.fn();
}
delete context.fn;
return result;
}
function fn(name, sex) {
this.name = name;
this.sex = sex;
console.log(this.name);
console.log(this.sex);
}
let obj = {};
fn.myapply(obj,['张三','女']);
执行结果
张三
女
bind 方法
/**
* 实现一个bind函数
*/
Function.prototype.mybind = function(context) {
if (typeof this !== 'function') {
return new Error("不是一个函数");
}
let _this = this; //保存当前函数
let args = [...arguments].slice(1);
return function F(...newArgs) {
//bind返回的是个函数,所以可以实例化一个对象返回
if (this instanceof F) {
return new _this(...args,...newArgs);
} else {
return _this.apply(context,args.concat(newArgs));
}
}
}
function parent(sex) {
console.log(sex);
console.log(this.name);
}
let Son = {
name: 'zhangsan'
}
let son = parent.mybind(Son,'男');
son();
执行结果
男
zhangsan
instanceof判断属性
/**
* 实现一个instanceof的判断方法
* instanceof方法的判断是通过隐式原型属性__proto__判断的
* 只要在这条原型链上的对象都为true
*/
function myInstanceoF(left, right) {
//保存左边构造函数的原型对象
let prototype = right.prototype;
left = left.__proto__;
while (true) {
if (left == null) {
return false;
} else if (left == prototype) {
return true;
}
left = left.__proto__;
}
}
function Hello(name) {
this.name = name;
}
let test = new Hello('张三');
let arr = new Array('33');
console.log(myInstanceoF(arr, Array));
console.log(myInstanceoF(test, Hello));
console.log(myInstanceoF(arr, Hello));
执行结果为
true
true
false