前言
这是underscore.js源码分析的第五篇,如果你对这个系列感兴趣,欢迎点击
underscore-analysis/ watch一下,随时可以看到动态更新。
事情要从js中的
this
开始说起,你是不是也经常有种无法掌控和知晓它的感觉,对于初学者来说,this
简直如同回调地狱般,神乎其神,让人无法捉摸透。但是通过原生js中的bind方法,我们可以显示绑定函数的this
作用域,而无需担心运行时是否会改变而不符合自己的预期。当然了下划线中的bind也是模仿它的功能同样可以达到类似的效果。
bind简单回顾
我们从mdn上的介绍来回顾一下bind的使用方法。
bind方法创建一个新的函数, 当被调用时,它的this关键字被设置为提供的值。
语法
|
|
简单地看一下这些参数的含义
thisArg
当绑定函数被调用时,该参数会作为原函数运行时的this指向,当使用new 操作符调用绑定函数时,该参数无效。
arg1, arg2, …
当绑定函数被调用时,这些参数将置于实参之前传递给被绑定的方法。
绑定this作用域示例
|
|
通过以上简单示例,我们知道了第一个参数的作用就是绑定函数运行时候的this
指向
第二个参数开始起使用示例
|
|
bind可以使一个函数拥有预设的初始参数。这些参数(如果有的话)作为bind的第二个参数跟在this(或其他对象)后面,之后它们会被插入到目标函数的参数列表的开始位置,传递给绑定函数的参数会跟在它们的后面。
参数的使用基本上明白了,我们再来看看使用new去调用bind之后的函数是怎么回事。
|
|
有没有发现bindPerson内部的this不再是bind的第一个参数obj,此时obj已经不再起效了。
实际上bind的使用是有一定限制的,在一些低版本浏览器下不可用,你想不想看看下划线中是如何实现一个兼容性好的bind呢!!!come on
下划线中bind实现
源码
|
|
executeBound实现
|
|
上面的源码都做了相应的注释,我们着重来看一下executeBound
的实现
先看一下这些参数都代表什么含义
- sourceFunc:原函数,待绑定函数
- boundFunc: 绑定后函数
- context:绑定后函数
this
指向的上下文 - callingContext:绑定后函数的执行上下文,通常就是 this
- args:绑定后的函数执行所需参数
ok,我们来看一下第一句
|
|
这句话是为了判断绑定后的函数是以new关键字被调用还是普通的函数调用的方式,举个例子
|
|
所以如果你希望自己写的构造函数无论是new
还是没用new
都起效的话可以用下面的代码
|
|
我们回到executeBound
的解析
|
|
callingContext
是被绑定后的函数的this
作用域,boundFunc
就是那个被绑定后的函数,那么通过这个if判断,当为非new
调用形式的时候,直接利用apply
处理即可。
但是如果是用new
调用的呢?我们看下面这段代码,别看短短的四行代码里面知识点挺多的呢!
|
|
好,到这里,我有一个疑问,baseCreate
是个什么鬼?
|
|
是不是好简单,就是实现了原生的Object.create用来做一些继承的事情。
结尾
文章很简短,知道怎么实现一个原生的bind就行。如果你对apply、call和this感兴趣,欢迎查看