22.call方法的深入
var obj = { name: "zhangsna" }
function fn () {
console.log(this)
}
fn()
fn.call(obj)
call方法的作用:
1.首先让原型上的call方法执行,在执行call方法的时候,我们让fn方法中的this变为第一个参数值obj,然后再把fn这个函数执行
自己模拟内置的call方法,写一个myCall方法,深入探讨call方法的执行原理
Function.prototype.myCall = function (context) {
//(1) 让this这个函数中的this关键字变为context
eval( this.toString().replace("this","context") )
// (2)让this方法执行
this()
}
function fn1() { console.log(1) }
function fn2 () { console.log(2) }
fn1.call(fn2) // 首先fn1通过原型链机制找到Function.prototype上的call方法,并且让call方法执行 -> 此时call这个方法中的this就是我要操作的fn1
在call方法代码执行的过程中,首先让fn1中的this关键字变成fn2,然后再让fn1这个方法执行
fn1.call.call(fn2) // fn1.call 首先fn1通过原型链找到Function.prototype上的call方法,然后在让call方法通过原型在找到Function.prototype上的call方法(因为call本身的值也是一个函数,所以同样可以找到Function.prototype),在第二次找到call的时候,让方法执行,方法中的this是fn1.call,首先让这个方法中的this变为fn2,然后再让fn1.call执行
function zhangsan( context ) {
//(1) 让this这个函数中的this关键字变为context
// (2)让this方法执行
this()
}
Function.prototype.call = zhangsan;
fn1.call.call(fn2); // 2
// fn1.call ->zhangsan
// zhangsan.call (fn2) ->先让call方法执行,call中的this是zhangsan,让zhangsan中的this变成fn2,再让zhangsan执行 -》2
fn1.call.call.call.call.call(fn2); // 2
Function.prototype.call(fn1) // undefined call中的this是Function.prototype而Function.prototype是一个空函数
Function.prototype.call.call.call.call(fn1) // 1