JavaScript深入之call和apply的模拟实现,call和apply的模拟实现

JavaScript 深切之call和apply的模拟达成

2017/05/25 · JavaScript
· apply,
call

初稿出处: 冴羽   

已离开简书,原因参见
http://www.jianshu.com/p/0f12350a6b66。

初稿出处

JavaScript深入之call和apply的模拟完结

JavaScript 深远之bind的模仿完结

2017/05/26 · JavaScript
· bind

初稿出处: 冴羽   

call

一句话介绍 call:

call() 方法在选择一个点名的 this
值和若干个指定的参数值的前提下调用有个别函数或措施。

JavaScript深入之call和apply的模拟实现,call和apply的模拟实现。举个例子:

var foo = { value: 1 }; function bar() { console.log(this.value); }
bar.call(foo); // 1

1
2
3
4
5
6
7
8
9
var foo = {
    value: 1
};
 
function bar() {
    console.log(this.value);
}
 
bar.call(foo); // 1

留意两点:

  1. call 改变了 this 的指向,指向到 foo
  2. bar 函数执行了

虽卑不足道,但也要有友好的千姿百态。

call

大家在模仿 call在此之前,先看看 call完成了怎么样功用。

        var foo = {
            value: 1
        };

        function bar() {
            console.log(this.value);
        }

        bar.call(foo); // 1

留神两点:
1.call 改变了 this 的指向,指向到 foo
2.bar 函数执行了

bind

一句话介绍 bind:

bind() 方法会创建叁个新函数。当这些新函数被调用时,bind()
的率先个参数将用作它运转时的
this,之后的一系列参数将会在传递的实参前传出作为它的参数。(来自于 MDN
)

因而大家得以率先得出 bind 函数的多少个特征:

  1. 回来1个函数
  2. 能够流传参数

效仿达成率先步

那正是说大家该怎么模拟落成那四个功能呢?

试想当调用 call 的时候,把 foo 对象改造成如下:

var foo = { value: 1, bar: function() { console.log(this.value) } };
foo.bar(); // 1

1
2
3
4
5
6
7
8
var foo = {
    value: 1,
    bar: function() {
        console.log(this.value)
    }
};
 
foo.bar(); // 1

以此时候 this 就对准了 foo,是或不是不会细小略吗?

唯独如此却给 foo 对象自笔者添加了壹脾质量,那可不行呀!

不过也不用担心,我们用 delete 再删除它不就好了~

就此我们模拟的步调能够分成:

  1. 将函数设为对象的属性
  2. 执行该函数
  3. 剔除该函数

上述个例证为例,正是:

// 第一步 foo.fn = bar // 第二步 foo.fn() // 第三步 delete foo.fn

1
2
3
4
5
6
// 第一步
foo.fn = bar
// 第二步
foo.fn()
// 第三步
delete foo.fn

fn 是目的的属性名,反正最终也要删减它,所以起成如何都不在乎。

依照那些思路,大家能够尝尝着去写第二版的 call2 函数:

// 第贰版 Function.prototype.call2 = function(context) { //
首先要获得调用call的函数,用this能够收获 context.fn = this;
context.fn(); delete context.fn; } // 测试一下 var foo = { value: 1 };
function bar() { console.log(this.value); } bar.call2(foo); // 1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 第一版
Function.prototype.call2 = function(context) {
    // 首先要获取调用call的函数,用this可以获取
    context.fn = this;
    context.fn();
    delete context.fn;
}
 
// 测试一下
var foo = {
    value: 1
};
 
function bar() {
    console.log(this.value);
}
 
bar.call2(foo); // 1

刚巧能够打字与印刷 1 哎!是还是不是很春风得意!(~ ̄▽ ̄)~

小说能够在自家的 Github
https://github.com/mqyqingfeng/Blog
查看

宪章实现率先步


那便是说大家该怎么模拟调用call时的那七个效益啊?
试想当调用 call 的时候,把 foo 对象改造成如下:

        var foo = {
            value: 1,
            bar: function () {  // 把this指向foo
                console.log(this.value)  
            }
        };

        foo.bar(); // 1  //执行 bar 函数

但是这么却给 foo 对象自我添加了1个属性,那可尤其呀!
可是也不用担心,大家用 delete 再删除它不就好了~
从而大家模拟的步骤能够分成:

  1. 将函数设为对象的性质
  2. 实施该函数
  3. 除去该函数

如上个例证为例,便是:

        // 第一步,把this指向foo
        foo.fn = bar
        // 第二步,执行bar函数
        foo.fn()
        // 第三步,删除多余属性
        delete foo.fn

fn 是指标的属性名,反正最后也要删减它,所以起成怎么样都无所谓。
据书上说这一个思路,我们能够品尝着去写第①版的 call2 函数:

        var foo = {
            value: 1
        };

        function bar() {
            console.log(this.value);
        }

        Function.prototype.call2 = function(context) {
            context.fn = this; // 把this指向foo
            context.fn();  // 执行bar函数
            delete context.fn;
        }

        bar.call2(foo);

回去函数的模仿完毕

从第②个特征开端,大家举个例子:

var foo = { value: 1 }; function bar() { console.log(this.value); } //
重临了几个函数 var bindFoo = bar.bind(foo); bindFoo(); // 1

1
2
3
4
5
6
7
8
9
10
11
12
var foo = {
    value: 1
};
 
function bar() {
    console.log(this.value);
}
 
// 返回了一个函数
var bindFoo = bar.bind(foo);
 
bindFoo(); // 1

至于钦点 this 的针对,大家得以应用 call 大概 apply 达成,关于 call 和
apply
的模拟达成,能够查看《JavaScript深切之call和apply的模拟完毕》。大家来写第叁版的代码:

// 第一版 Function.prototype.bind2 = function (context) { var self =
this; return function () { self.apply(context); } }

1
2
3
4
5
6
7
8
// 第一版
Function.prototype.bind2 = function (context) {
    var self = this;
    return function () {
        self.apply(context);
    }
 
}

相关文章