Hand write call, apply, bind
Function.prototype._call = function (ctx, ... args) {
const fn = Symbol('fn') // Declare a unique symbol attribute (to prevent overwriting other variables)
console.log('... '. args)// a,b
console.log('args', args) // [a,b]
// let arg = array. from(args) // Let arg = Array
// console.log('arg', arg)
let context = ctx || window // If no this is passed, the window object is bound by default
context.fn = this // Function assignment, change this point
let result = args.length > 0? context.fn(... args) : context.fn()// Execute the current function and check if there are any arguments
delete context.fn // Delete the fn property we overwrote, because we just want to borrow this, we can't change the object
return result // Return the result
}
Function.prototype._apply = function (ctx, args = []) {
const fn = Symbol('fn')
if(! (args && argsinstanceof Array)) {
throw ('Please pass in an array')}let context = ctx || window
context.fn = this
let result = args.length > 0? context.fn(... args) : context.fn()delete context.fn
return result
}
Function.prototype._bind = function (ctx, ... args) {
let that = this
return function () {
returnthat._call(ctx, ... args) } }var name = "1";
var obj = {
name: 2.prop: {
name: 3.getName: function (age, s) {
return {
name: this.name,
age: age,
s: s
}
}
}
}
console.info(obj.prop.getName(3.4)); / / 3, 3, 4
console.info(obj.prop.getName.call(obj, 3.4)); / / 2, 3, 4
console.info('_call achieve', obj.prop.getName._call(this.3.4)); // This is window 1, 3, 4
console.info('_apply achieve', obj.prop.getName._apply(this[2.3])); // This is window 1, 2, 3
let bindHandle = obj.prop.getName._bind(this.2.3)
console.log('bindHandle()', bindHandle())// This is window 1, 2, 3
Copy the code
Follow-up Article Output
- In handwritten Bind, there’s actually a reference to closures, and I’ll talk about closures in the next article