Last active
September 14, 2021 03:15
-
-
Save Teemwu/d771e7222853ba472799fb9247025e30 to your computer and use it in GitHub Desktop.
手写 apply、call、bind 方法
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
/** | |
* 手写 apply 方法 | |
* @param {*} context 上下文 this | |
* @returns 指定的 this 值和参数 | |
*/ | |
Function.prototype._apply = function (context) { | |
// 判断上下文 context 是否存在 | |
// 不存在则指向 window | |
context = context || window; | |
// 获取随机 id | |
var unique = 'id' + Math.random(); | |
// 判断 context 原型中是否存在 unique 属性 | |
while (context.hasOwnProperty(unique)) { | |
// 重新生成 unique | |
unique = 'id' + Math.random(); | |
} | |
context[unique] = this | |
var arr = arguments[1] | |
if (!arr) { | |
result = context[unique]() | |
} else { | |
result = eval('context[unique](' + arr + ')') | |
} | |
delete context[unique] | |
return result | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
/** | |
* 手写 bind 方法 | |
* @param {*} context 调用函数的上下文 this | |
* @returns 新的构造函数 | |
*/ | |
Function.prototype._bind = function (context) { | |
// 此处 this 为调用者 | |
var _this = this; | |
var _slice = Array.prototype.slice; | |
var _toString = Object.prototype.toString | |
var fnType = '[object Function]' | |
// 必须是 function 类型才能调用 _bind 方法 | |
if (typeof _this !== 'function' || _toString.call(_this) !== fnType) { | |
throw new TypeError('Function.prototype._bind - waht is trying to be bound is not callable') | |
} | |
// 获取除上下文 this 外的参数 | |
var args = _slice.call(arguments, 1); | |
// 定义一个空的构造函数 | |
var binder = function () { }; | |
// 构建要返回的函数 | |
var bound = function () { | |
// 判断 binder 是否在 _this 的原型链上 | |
var _instanceof = _this instanceof binder; | |
// 获取上下文 this | |
var target = _instanceof ? _this : context; | |
// 获取函数参数 | |
var _args = args.concat(_slice.call(arguments)); | |
// 返回新的构造函数 | |
return _this.apply(target, _args); | |
} | |
if (_this.prototype) { | |
// 空构造函数原型指向 _bind 函数的原型 | |
binder.prototype = _this.prototype; | |
} | |
// 空构造函数的实例赋值给返回函数原型 | |
bound.prototype = new binder(); | |
return bound; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 手写 call 方法 | |
* @param {*} context this 上下文. | |
* @returns 指定的 this 值和参数 | |
*/ | |
Function.prototype._call = function (context) { | |
context = context || window; | |
var unique = 'id' + Math.random(); | |
while (context.hasOwnProperty(unique)) { | |
unique = 'id' + Math.random(); | |
} | |
context[unique] = this; | |
var args = []; | |
for (var i = 1, len = arguments.length;i < len;i++) { | |
args.push('arguments[' + i + ']'); | |
} | |
var result = eval('context[unique](' + args + ')'); | |
delete context[unique]; | |
return result; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment