深入之bind的模拟实现,JavaScript深入之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的模拟实现,JavaScript深入之call和apply的模拟实现。
· bind

原作出处: ca88手机版登陆网页,冴羽   

call

一句话介绍 call:

call() 方法在行使一个钦赐的 this
值和几何个钦赐的参数值的前提下调用某些函数或格局。

举个例证:

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,之后的1系列参数将会在传递的实参前传出作为它的参数。(来自于 MDN
)

因此大家得以率先得出 bind 函数的多个特色:

  1. 重返2个函数
  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: 一 };
function bar() { console.log(this.value); } bar.call2(foo); // 一

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

88bf必发唯一官方网站 ,恰恰能够打字与印刷 一 哎!是否很洋洋得意!(~ ̄▽ ̄)~

小说能够在自个儿的 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 对象自笔者添加了二个属性,那可尤其啊!
不过也不用担心,我们用 delete 再删除它不就好了~
据此大家模拟的手续能够分为:

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

上述个例子为例,正是:

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

fn 是目的的属性名,反正最终也要删减它,所以起成怎么样都无所谓。
依照那一个思路,大家能够尝试着去写第3版的 call二 函数:

        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: 一 }; function bar() { console.log(this.value); } //
重临了1个函数 var bindFoo = bar.bind(foo); bindFoo(); // 一

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的模拟实现》。大家来写第2版的代码:

// 第一版 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);
    }
 
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图