call
Function.prototype.myCall = function (obj = window) { // 不传参默认为window
obj.fn = this
const args = [...arguments].slice(1)
const res = obj.fn(...args)
delete obj.fn
return res
}
var obj = {
x: 10
}
function foo() {
console.log(this); // { x: 10, fn: [Function: foo] }
console.log(this.x); // 10
}
foo.myCall(obj);
代码解析:
var obj = {
x: 10
}
Function.prototype.myCall = function (context = window) {
context.fn = this // this指向实例,此例为foo
// console.log(this); // [Function: foo]
// console.log(context); // { x: 10, fn: [Function: foo] }
const args = [...arguments].slice(1) // 去掉第一个参数,就是context,这里就是obj
// console.log(args); // [1,2]
const result = context.fn(...args)
delete context.fn // 删除方法属性fn
return result
}
function foo(a, b) {
console.log(this) // { x: 10, fn: [Function: foo] }
console.log(a + b) // 3
}
foo.myCall(obj, 1, 2);
apply和call实现类似,不同的就是参数的处理:
Function.prototype.myApply = function (obj = window) {
obj.fn = this
let result
if (arguments[1]) {
result = obj.fn(...arguments[1])
} else {
result = obj.fn()
}
delete obj.fn
return result
}
var obj = {
x: 10
}
function foo() {
console.log(this); // { x: 10, fn: [Function: foo] }
console.log(this.x); // 10
}
foo.myApply(obj);
代码解析:
var obj = {
x: 1
}
Function.prototype.myApply = function (obj = window) {
obj.fn = this
let res
if (arguments[1]) {
res = obj.fn(...arguments[1])
} else {
res = obj.fn()
}
delete obj.fn
return res
}
function f1(a, b) {
console.log(this);
console.log(this.x);
console.log(a + b);
}
f1.myApply(obj, [1, 2])
bind
Function.prototype.mybind = function (context = window) { // 原型上添加mybind方法
var argumentsArr = Array.prototype.slice.call(arguments) // 类数组转数组
var args = argumentsArr.slice(1) // 后面的参数
var self = this // 调用的方法本身
return function () { // 返回一个待执行的方法
var newArgs = Array.prototype.slice.call(arguments) // 返回函数的arguments
self.apply(context, args.concat(newArgs)) // 合并两args
}
}
var obj = {
x: 10
}
function foo() {
console.log(this); // {x: 10}
console.log(this.x); // 10
}
foo.mybind(obj)();
代码解析:
var obj = {
x: 10
}
Function.prototype.myBind = function (obj = window) {
obj.fn = this // this指向实例,此例为foo
const res = function () { // 包裹在一个函数里面
obj.fn(...arguments)
delete obj.fn // 删除方法属性fn
}
return res
}
function foo(a, b) {
console.log(this) // { x: 10, fn: [Function: foo] }
console.log(a + b)
}
foo.myBind(obj)(1, 2)