我的编程空间,编程开发者的网络收藏夹
学习永远不晚

JavaScriptbind函数手写教程

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

JavaScriptbind函数手写教程

经常会看到网上各种手写bind的教程,下面是我在自己实现手写bind的过程中遇到的问题与思考。如果对于如何实现一个手写bind还有疑惑的话,那么可以先看看上面两篇文章。

手写bind vs 原生bind

我们先使用一个典型的手写bind的例子,代码如下:

Function.prototype.bind2 = function (context) {
    if (typeof this !== "function") {
      throw new Error("Function.prototype.bind - what is trying to be bound is not callable");
    }
    var self = this;
    var args = Array.prototype.slice.call(arguments, 1);
    var fNOP = function () {};
    var fBound = function () {
        var bindArgs = Array.prototype.slice.call(arguments);
        return self.apply(this instanceof fNOP ? this : context, args.concat(bindArgs));
    }
    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();
    return fBound;
}

我们首先用原生bind运行一下代码

function Foo(a) {this.a = a}
Foo.prototype.sayHi = function( ) {}
let _Foo = Foo.bind(undefined, 'a')
new _Foo() 

更多面试题解答参见前端手写面试题详细解答

然后使用手写版代码,运行同样的代码

function Foo(a) {this.a = a}
Foo.prototype.sayHi = function( ) {}
let _Foo = Foo.bind2(undefined, 'a')
new _Foo() 

我们可以看到相比原生bind方法,手写版的bind方法返回的构造函数,构造出来的新对象会比原生的多一层__proto__。而这个__proto__产生的原因就是在很多教程中提到的防止原型链篡改。

这也就是为什么很多的文章会告诉你,为什么要添加下面的代码。

var fNOP = function () {};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();

这段代码中,使用了一个空函数作为中转,相当于Object.create(fBound.prototype)。具体可以查看文章开头给出的文章,里面的详细的说明。

规范中的bind

既然说道,加上面的代码是为了防止原型链篡改。我就想看看原生的bind如何处理这个问题的呢?

function Foo(a) {this.a = a}
Foo.prototype.sayHi = function( ) {}
let _Foo = Foo.bind(undefined, 'a')
_Foo.prototype.sayHi = function( ) {console.log('篡改的_Foo的sayHi方法')}
(new _Foo().sayHi())

我发现在运行上面的代码,程序执行到修改_Foo的原型方法的语句时,就已经报错了。提示表明_Foo没有prototype属性!既然没有prototype属性,那么是不是也就不用处理原型链篡改的问题了呢?

之后,我查了一下规范, 在NOTE中,有下面一段话。明确指出了bind返回的函数是没有prototype属性,这也多少印证了上面的猜想。

Function objects created using Function.prototype.bind do not have a prototype property or the [[Code]], [[FormalParameters]], and [[Scope]] internal properties.

其中需要注意的有一点是这条:

Set the [[Prototype]] internal property of F to the standard built-in Function prototype object as specified in 15.3.3.1.

我自己理解的意思是是bind出来的函数对象的prototype属性是内建的Function.prototype属性, 这里应该是说明了为什么原生的bind不会多一层__proto__属性

小结

写这篇的目的是总结下自己在实现bind过程中遇到的问题,记录探究的过程。通过一系列手写原生方法,锻炼了我们对于原理的进一步认识。但是也要注意验证,实际去操作几次,可能得出自己的经验。如果有更多的两者对比的发现,可以在评论里告诉我,欢迎各位大佬斧正。

到此这篇关于JavaScript bind函数手写教程的文章就介绍到这了,更多相关JS bind函数内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

JavaScriptbind函数手写教程

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

JavaScriptbind函数手写教程

bind()方法主要就是将函数绑定到某个对象,bind()会创建一个函数,函数体内的this对象的值会被绑定到传入bind()第一个参数的值,当然这是绑定哦,不是像call、apply一样直接执行,apply要执行的话还得自己调用
2022-12-19

chatGPT教我写compose函数的详细过程

这篇文章主要介绍了chatGPT教我写compose函数,文中给大家介绍了chatGPT过程概略,本文结合实例代码图文给大家讲解的非常详细,需要的朋友可以参考下
2023-02-23

JS中callapplybind函数手写实现demo

这篇文章主要为大家介绍了JS中callapplybind函数手写实现demo,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-03-15

win8 手写输入实现大小写切换教程(图文)

知识点分析:正常手写输入的是大写,识别出来既是大写,手写输入小写既是小写,如图:但若输入的为S这样的大小写一样的字母时,便不好判断大小写。操作步骤:其实大小写可以在输入面板中切换:点击字母上方的向下小三角,在里面去选择即可,如图:
2022-06-04

手把手教你在Python使用plot()函数画图

本篇文章给大家带来了关于python的相关知识,其中主要介绍了关于使用plot()函数画图的相关问题,包括了该函数的基本认识和使用,以及该函数数据可视化图画以及基本参数设置,下面一起来看一下,希望对大家有帮助。在使用Python进行数据可视化编程中matplotlib库是我们用来对数据进行画图常用的第三方库。其中含有各类函数也就是不同类型的图形,要使用matplotlib库中的函数就需要了解函数所需
2022-06-15

Pythoninput()函数案例教程

在Python中,input()函数用于获取用于的输入,并给出提示。input()函数,总是返回string类型,因此,我们可以使用input()函数,获取用户输入的任何数据类型,这篇文章主要介绍了Pythoninput()函数案例详解,需要的朋友可以参考下
2023-01-11

PHP 函数使用教程

php 函数允许将代码模块化,方便重用。要创建函数,使用 function 关键字,指定函数名、参数和函数体。要调用函数,使用其名称和参数。函数可以接受参数并返回一个值。在函数内部声明的变量位于局部作用域,要访问全局变量,需使用 globa
PHP 函数使用教程
2024-04-10

c#线程函数怎么写

在 c# 中,使用 threadstart 委托和 thread 类创建和启动线程。具体步骤包括:创建线程函数,指定执行函数(functionsignature: void functionname())。使用 threadstart 委托
c#线程函数怎么写
2024-05-14

JavaScript手写源码之omit函数的实现

最近突然有个新的想法,想去看看前端的小库来提升自己的编码能力。但是又不知道怎么去证明自己是否真的看懂了,那就实现一个omit函数吧
2023-02-09

手把手教你拿捏vue cale()计算函数使用

这篇文章手把手教你拿捏vue cale()计算函数使用,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-05-14

MySQL基础教程6 —— 函数之控制流程函数

语法:CASE value WHEN [compare-value] THEN result [WHEN [compare-value] THEN result ...] [ELSE result] END CASE WHEN [condi
2022-05-20

编程热搜

目录