day112-手写原生bind()-2

前言

之前实现的bind(),能返回新函数,也能参数传递,实际原生的bind()还能实现构造函数的效果。这个用法也是很常用的。其中还涉及到绑定函数时,需要了解new 的模拟实现


MDN上作为构造函数的绑定函数,如下。

// bind() 作为构造函数的绑定函数
function Point(x, y) {
this.x = x
this.y = y
}
Point.prototype.toString = function() {
return this.x + ',' + this.y
}

var YAxisPoint = Point.bind(null, 0/*x*/)
var axisPoint = new YAxisPoint(5)
var result = axisPoint.toString()

console.log(result) // 0,5

做一些改动。

// 改动
var contextObj = {
x: '1',
y: '2'
}
var YAxisPoint2 = Point.bind(contextObj)
var result2 = new YAxisPoint('1', '9')
// 绑定的 this 失效
console.log(YAxisPoint2.x) // undefined

实现代码

代码里有些要注意的点。


Function.prototype.myBind = function (ct) {
var _self = this
var args = Array.prototype.slice.call(arguments, 1)
// 原型变量
var fNOP = function () {}

var fBound = function () {
// 注意:arguments是当前函数的参数
var bindArgs = Array.prototype.slice.call(arguments)
// fBound做构造函数时,将绑定函数的this指向该实例,让实例获得来自绑定函数的值
return _self.apply(fNOP.prototype.isPrototype(this) ? this : ct, args.concat(bindArgs))
}
// 实例继承绑定函数原型
// fBound.prototype = this.prototype
// 这里args长度会变化???
if (this.prototype) {
// 维护原型关系,空函数中转
fNOP.protytype = this.prototype
}
fBound.prototype = new fNOP()
return fBound
}

一些细节:
这部分实现创建的绑定函数所有的 length 属性并不是同ECMA-262标准一致的:它创建的函数的 length 是0,而在实际的实现中根据目标函数的 length 和预先指定的参数个数可能会返回非零的 length。

参考

JavaScript深入之bind的模拟实现
MDN(中文版)Function​.prototype​.bind()
MDN(英文版)Function​.prototype​.bind()

文章作者: lmislm
文章链接: http://lmislm.com/2019/05/04/2019-05-04/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 LMISLMのBlog