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