第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定

JavaScript專(zhuān)題之模擬實(shí)現(xiàn)bind

標(biāo)簽:
JavaScript

本文共 1100 字,读完只需 4 分钟

概述

前一篇文章我们尝试模拟实现了 call 和 apply 方法,其实 bind 函数也可以用来改变 this 的指向。bind 和 call和 apply 两者的区别在于,bind 会返回一个被改变了 this 指向的函数。

本文介绍如何模拟实现 bind 函数:

首先观察 bind 函数有什么特点:

var person = {
    name: 'jayChou'
}

function say(age, sex) {
    console.log(this.name, age, sex);
}

var foo = say.bind(person, '男', 39);

foo();  // jayChou 男 39
  1. 返回一个函数
  2. 函数参数以逗号的形式传入
  3. 改变了 this 的指向

一、call 简单实现

既然 bind 内部也要用改变 this 指向,我们可以用现成的 call 函数来实现这一功能。

Function.prototype.newBind = function(context) {
    if(typeof this !== 'function') {
        throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
    }
    var self = this;
    return function () {
        return self.call(context)
      }
}

说明一下:
if 判断是为了校验,只能让函数来调用此方法,并抛出错误。
第二个 return 是为了让返回的函数有返回值的功能。

测试一下:

var person = {
    name: 'jayChou'
};

var say = function() {
    console.log(this.name);
}

var foo = say.newBind(person);
foo();  // jayChou

成功啦。

二、传递参数

刚才的函数是没有传递参数,当然不行,所以我们想办法把函数的参数也传递进去。

bind 函数有个特点,就是在绑定的时候可以传参,返回的函数还可以继续传参。

var person = {
    name: 'jayChou'
};

var say = function(p1, p2) {
    console.log(this.name, p1, p2);
}

var foo = say.bind(person, 18);
foo(20);  // jayChou 18 20

还可以写成:

say.bind(person, 18)(20); // jayChou 18 20

好,进入正题,考虑传参的事。在前面的文章,我们讲过 arguments 类数组对象的一些特性,不能直接调用数组的方法,但是可以用原型方法间接来调用,我们采用 apply 的方式来传递参数。

Function.prototype.newBind = function(context) {
    if(typeof this !== 'function') {
        throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
    }
    var self = this;
    var args = Array.prototype.slice.call(arguments, 1);  // 间接调用数组方法,获取第一次传的参数
    
    return function () {
        var innerArgs = Array.prototype.slice.call(arguments);
        return self.apply(context, args.concat(innerArgs))
      }
}


var person = {
    name: 'jayChou'
};

var say = function(p1, p2) {
    console.log(this.name, p1, p2);
}

var foo = say.newBind(person, 18);  // 第一次传参
foo(20);  // 第二次传参

最后输出:

jayChou 18 20

结果正确,以上就完成了 bind 函数基本功能的实现。

但是!

三、作为构造函数时?

bind 函数其实还有一个非常重要的特点:

bind返回的函数如果作为构造函数,搭配new关键字出现的话,我们的绑定this就需要“被忽略”。

意思就是指:当使用 nuw 关键字把 bind 返回的函数作为构造函数,之前改变了指向的 this 就失效了。返回的函数的 this 就关联到了构造函数的实例对象上。

针对这个特点,需要再做一些修改:

Function.prototype.newBind = function(context) {
    if(typeof this !== 'function') {
        throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
    }
    var self = this;
    var args = Array.prototype.slice.call(arguments, 1);  // 间接调用数组方法,获取第一次传的参数
    
    let tempFn = function {};  // 利用一个空函数作为中转
    
    tempFn.prototype = this.prototype;  // 修改返回函数的 prototype 为绑定函数的 prototype,实例就可以继承绑定函数的原型中的值
    
    var resultFn = function () {
        var innerArgs = Array.prototype.slice.call(arguments);
        if (this instanceof tempFn) {  // 如果 返回函数被当做构造函数后,生成的对象是 tempFn 的实例,此时应该将 this 的指向指向创建的实例。
            return fn.apply(this, args.concat(innerArgs));
        } else {
            return self.apply(context, args.concat(innerArgs))
        }
      }
      
    resultFn = new tempFn();
    return resultFn;
}

总结

本文尝试模拟实现了 bind 函数,bind 函数与 call,apply 函数的区别在于,bind 函数返回一个指定了 this 的函数,函数并未执行。其次,当返回的函数作为构造函数时,之前绑定的 this 会失效。

點(diǎn)擊查看更多內(nèi)容
TA 點(diǎn)贊

若覺(jué)得本文不錯(cuò),就分享一下吧!

評(píng)論

作者其他優(yōu)質(zhì)文章

正在加載中
  • 推薦
  • 評(píng)論
  • 收藏
  • 共同學(xué)習(xí),寫(xiě)下你的評(píng)論
感謝您的支持,我會(huì)繼續(xù)努力的~
掃碼打賞,你說(shuō)多少就多少
贊賞金額會(huì)直接到老師賬戶(hù)
支付方式
打開(kāi)微信掃一掃,即可進(jìn)行掃碼打賞哦
今天注冊(cè)有機(jī)會(huì)得

100積分直接送

付費(fèi)專(zhuān)欄免費(fèi)學(xué)

大額優(yōu)惠券免費(fèi)領(lǐng)

立即參與 放棄機(jī)會(huì)
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢(xún)優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)

舉報(bào)

0/150
提交
取消