// call函数的签名
fun.call(thisArg, arg1, arg2, ...)
复制代码
call函数能够这样理解数组
参数:app
call函数把某个方法的this改为了第一个参数。给该函数传入多个参数,并执行当前函数。函数
call函数有这么几个要点,须要理解:ui
/* 把函数当成对象,而后删除对应的属性值 */
Function.prototype.call2 = function (context) {
// 判断当前的this对象是否为null,为空指向window
var context = context || window;
// 首先要获取调用call的函数,用this能够获取
context.fn = this;
var args = [];
// 获取call的参数
for(var i = 1, len = arguments.length; i < len; i++) {
args.push('arguments[' + i + ']');
}
// eval执行该函数
var result = eval('context.fn(' + args +')');
// 删掉调用对象的这个属性
delete context.fn
return result;
}
复制代码
// apply的函数签名
func.apply(thisArg, [argsArray])
复制代码
apply函数和call函数实现的是相同的功能this
apply函数的参数:spa
实现:prototype
Function.prototype.apply = function (context, arr) {
// 判断当前的this对象是否为null,为空指向window
var context = context || window;
// 首先要获取调用call的函数,用this能够获取
context.fn = this;
var result;
if (!arr) {
result = context.fn();
}
else {
var args = [];
for (var i = 0, len = arr.length; i < len; i++) {
args.push('arr[' + i + ']');
}
result = eval('context.fn(' + args + ')')
}
delete context.fn
return result;
}
复制代码
// bind函数的函数签名
function.bind(thisArg[, arg1[, arg2[, ...]]])
复制代码
bind()方法建立一个新的函数,在bind()被调用时,这个新函数的this被bind的第一个参数指定,其他的参数将做为新函数的参数供调用时使用。code
参数:对象
bind() 函数生成的新函数,不能本身执行,须要手动执行一下。可是这个新函数的this永远都是bind的第一个参数。继承
由于 bind 还有一个特色,就是
一个绑定函数也能使用new操做符建立对象:这种行为就像把原函数当成构造器。提供的 this 值被忽略,同时调用时的参数被提供给模拟函数。
也就是说当 bind 返回的函数做为构造函数的时候,bind 时指定的 this 值会失效,但传入的参数依然生效
实现
Function.prototype.bind2 = function (context) {
// 调用bind的是不是函数作一个判断
if (typeof this !== "function") {
throw new Error("Function.prototype.bind - what is trying to be bound is not callable");
}
// 把调用者和要传给函数的参数保存一下。
var self = this;
// 获取bind2函数从第二个参数到最后一个参数
var args = Array.prototype.slice.call(arguments, 1);
// 建立一个空函数来中转
var fNOP = function () {};
var fBound = function () {
var bindArgs = Array.prototype.slice.call(arguments);
// 看成为构造函数时,this 指向实例,此时结果为 true,将绑定函数的 this 指向该实例,可让实例得到来自绑定函数的值
// 以上面的是 demo 为例,若是改为 `this instanceof fBound ? null : context`,实例只是一个空对象,将 null 改为 this ,实例会具备 habit 属性
// 看成为普通函数时,this 指向 window,此时结果为 false,将绑定函数的 this 指向 context
return self.apply(this instanceof fNOP ? this : context, args.concat(bindArgs));
}
// 修改返回函数的 prototype 为绑定函数的 prototype,实例就能够继承绑定函数的原型中的值
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
}
复制代码