call
函數
- 特色:
- 1)能夠改變咱們當前函數的this指向
- 2)還會讓當前函數執行
Function.prototype.call = function (context) {
if (typeof this !== 'function') {
throw new TypeError(`${this} is not a function`)
}
context = Object(context) || window;
context.fn = this;
let args = [];
for (let i = 1; i < arguments.length; i++) {
args.push('arguments['+i+']');
}
let r = eval('context.fn('+args+')');
delete context.fn;
return r;
}
複製代碼
題目自測
function fn1() {
console.log(this,arguments);
console.log(1);
}
function fn2() {
console.log(this,arguments);
console.log(2);
}
fn1.call(fn2,1,2);
fn1.call.call.call.call.call(fn2,1,2);
複製代碼
- 思路解析
fn1.call(fn2,1,2)
- 1)
call
執行傳入fn2
,1
,2
三個參數
- 2)
call
函數內部context = Object(fn2) = fn2
- 3)
fn2.fn = fn1
- 4)
args=['arguments[1]','arguments[2]']=[1,2]
- 5)
eval('context.fn('+args+')') = fn2.fn(1,2) = fn2.fn1(1,2)
fn1.call.call.call.call.call(fn2,1,2)
- 1)
call
執行傳入fn2
,1
,2
三個參數
- 2)
call
函數內部context = Object(fn2) = fn2
- 3)
fn2.fn = call
- 4)
args=['arguments[1]',arguments[2]]=[1,2]
- 5)
eval('context.fn('+args+')') = fn2.fn(1,2) = fn2.call(1,2)
- 6)
call
執行傳入1
,2
兩個參數
- 7)
call
函數內部context = Object(1) = Number{1}
- 8)
Number{1}.fn = fn2
- 9)
args=['arguments[1]']=[1]
- 10)
eval('context.fn('+args+')') = Number{1}.fn(2) = Number{1}.fn2(2)
- 注:屢次調用
call
的時候實際上是call
執行的時候內部又調用了一次call
,總共調用兩次
apply
函數
- 特色:
- 1)能夠改變咱們當前函數的this指向
- 2)還會讓當前函數執行
Function.prototype.apply = function (context,args) {
if (typeof this !== 'function') {
throw new TypeError(`${this} is not a function`)
}
context = Object(context) || window;
context.fn = this;
if(!args){
return context.fn();
}
let r = eval('context.fn('+args+')');
delete context.fn;
return r;
}
複製代碼
new
操做符
- 特色
- 新生成了對象
- 連接到原型
- 綁定
this
- 返回一個對象
function Animal(type) {
this.type = type ;
}
Animal.prototype.say = function () {
console.log('say');
}
let tiger = new Animal('tiger');
console.log(tiger);
--------------------------------------------------------
function mockNew(){
let Constructor = [].shift.call(arguments);
let obj = {};
obj.__proto__ = Constructor.prototype;
let r = Constructor.apply(obj,arguments)
return r instance Object ? r : obj;
}
let tiger = mockNew(Animal,'tiger');
console.log(tiger);
複製代碼
bind
函數
- 特色
- 綁定
this
指向
- 返回一個綁定後的函數(高階函數原理)
- 若是綁定的函數被
new
執行 ,當前函數的this
就是當前的實例
new
出來的結果能夠找到原有類的原型
Function.prototype.bind = function (context) {
if (typeof this !== 'function') {
throw new TypeError(`${this} is not a function`)
}
let that = this;
let bindArgs = Array.prototype.slice.call(arguments, 1);
function Fn() { };
function bindFn() {
let args = Array.prototype.slice.call(arguments);
that.apply(this instanceof bindFn ? this : context, bindArgs.concat(args));
}
Fn.prototype = that.prototype;
bindFn.prototype = new Fn();
return bindFn;
}
複製代碼