Skip to content

Instantly share code, notes, and snippets.

@Teemwu
Last active September 14, 2021 03:15
Show Gist options
  • Save Teemwu/d771e7222853ba472799fb9247025e30 to your computer and use it in GitHub Desktop.
Save Teemwu/d771e7222853ba472799fb9247025e30 to your computer and use it in GitHub Desktop.
手写 apply、call、bind 方法
'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
}
'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;
}
/**
* 手写 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