call apply bind

call方法深入

2017-03-04  本文已影响256人  阿九是只大胖喵

首先看数组中的一个方法:
Array.prototype.slice = function() {}

   var ary = [12, 23, 34];
    // ary.slice -> ary这个实例,通过原型链的查找机制,找到Array.prototype上的slice方法,此时是该函数的地址
    // ary.slice(); -> 让找到的slice方法执行,在执行slice方法的过程中,才把ary数组进行截取

call方法的作用:
-> 首先让原型上的call方法执行,在执行call方法的时候,让fn方法中的this变为第一个参数值obj;然后再把fn这个函数执行。

    var obj = {
        name: 'derrick'
    }
    function fn() {
        console.log(this);
    }
    fn(); // this -> window
    fn.call(obj); // this -> obj

自己模拟内置的call方法,写一个myCall方法,深入探讨call方法执行的原理。

    Function.prototype.myCall = function (context) {
        // -> myCall方法中的this就是当前要操作和改变其this关键字的那个函数

        // -> 1. 让fn中的this关键字变为context的值 -> obj
        // -> 让this这个函数中的"this关键字"变为context
        // var that = eval(this.toString().replace('this', context));

        // -> 2. 让fn方法在执行
        this();
    }
    fn.myCall(obj); // -> myCall方法中的this是fn

    function sum() {

    }
    sum.myCall(obj); // -> myCall方法中this是sum

下面看一道面试题:

    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这个方法执行 -> 最终执行结果为 1

    fn1.call.call(fn2); // -> fn1.call 首先fn1通过原型链机制找到Function.prototype上的call方法,
    // 然后再让call方法通过原型再找到Function原型上的call(因为call本身的值也是一个函数,所以同样可以找到Function.prototype),在
    // 第二次再找到call的时候,让方法执行,方法中的this是fn1.call, 首先让这个方法中的this变为fn2,然后再让fn1.call执行
    // -> 输出结果为 2

再次分析:

    function xxx(context) {
        // 1. 让this这个函数中的"this关键字"变为context
        // 2. 让this方法执行
        this();
    }
    Function.prototype.myCall = xxx;
    fn1.call.call(fn2);
    // -> fn1.call -> xxx;
    // -> xxx.call(fn2) -> 先让call方法执行,call中this是xxx,让xxx中的this变为fn2,
    // 再让xxx执行 -> 2

    fn1.call.call.call.call.call(fn2); // 2

    Function.prototype.call(fn1); // Funciton.prototype是空函数,将其执行就是空函数执行,直接销毁
    Function.prototype.call.call.call.call(fn1); // fn1() -> 1
上一篇 下一篇

猜你喜欢

热点阅读