function () {return this.greeting + ', ' + this.name + '!!!';}, {greeting: 'Hello', name: 'Rebecca'}
Hello, Rebecca!!!
function () {return this.greeting + ', ' + this.name + '!!!';}, {greeting: 'Hello', name: 'Rebecca'}Hello, Rebecca!!!
function speak(fn, obj) {
if (!Function.prototype.call) {
Function.prototype.call = function (ctx) {
let args = [];
ctx.fn = this;
for (var i = 1; i < arguments.length; i++) {
args.push("arguments[" + i + "]");
}
var result = eval("ctx.fn(" + args + ")");
delete ctx.fn;
return result;
};
}
if (!Function.prototype.apply) {
Function.prototype.apply = function (ctx, args) {
var temp = [];
ctx.fn = this;
for (var i = 0; i < args.length; i++) {
temp.push("args[" + i + "]");
}
var result = eval("ctx.fn(" + temp + ")");
delete ctx.fn;
return result;
};
}
if (!Function.prototype.bind) {
Function.prototype.bind = function (ctx) {
var fnToBind = this;
var slice = Array.prototype.slice;
var args = slice.apply(arguments, 1);
var fBound = function () {
var restArgs = slice.apply(arguments);
return fnToBind.apply(
this instanceof fBound ? this : ctx,
args.concat(restArgs)
);
};
fBound.prototype = Object.create(fnToBind.prototype);
fBound.constructor = fBound;
return fBound;
};
}
return fn.call(obj);
} 复习一下手写。
function speak(fn, obj) {
// 方法1 将函数fn直接挂载到obj上
obj.fn = fn;
return obj.fn();
// // 方法2 使用apply
// return fn.apply(obj);
// // 方法3 使用call
// return fn.apply(obj);
// // 方法4 使用bind
// return fn.bind(obj)();
}
function speak(fn, obj) { return fn.apply(obj, obj); }