1. Introduction

I was looking at the es6-Shim library recently and saw the syntax of the title in the first few dozen lines. At first sight, inner OS: What the hell is this? A face of deception. Why you can call bind directly after call? What is this syntax for? .

2. How to use this grammar and why

The usage is as follows. Personally, I think there are two reasons.

  • Can be used to process data that native apis cannot.
  • Make your code cleaner.

(1) Take the array push method as an example:

const push = Function.prototype.call.bind(Array.prototype.push)
function fn () {
    const args = arguments
    // Native push syntax like args.push(' I am pushed') cannot be used here because args is a pseudo-array.
    push(args, 'i am pushed')
    console.log(args)
}
fn()
Copy the code

(2) in detecting data types, a method is to use the Object. The prototype. ToString. Call.

// 1. Original usage
const objStr = Object.prototype.toString.call({})
console.log(objStr)
// [object Object]

const arrStr = Object.prototype.toString.call([])
console.log(arrStr)
// [object Array]
Copy the code

As you can see, the original usage method was too cumbersome to use in ES6-SHIM.

// 2
const toString = Function.prototype.call.bind(Object.prototype.toString)
toString({})
toString([])
...
Copy the code

Principle 3.

Analysis principle, we put the grammar Function. The prototype. Call the bind (Array) prototype) push) split apart, a little said.

3-1.Function.prototype.call.bind

At first glance, I didn’t understand the syntax at the beginning. I added bind after call. But call itself is a function. You can call bind if it’s a function. After the call, this in call points to the value of the bind binding. That is:

const obj = {}
// Bind returns a new function that works the same way as call, requiring the source of bind.
const fn = Function.prototype.call.bind(obj)
fn(this, args)
. / / the Function actually. Prototype. Call the bind (obj) is equivalent to obj. Call
// Because bind binds this value, which always points to the caller of the function. So.bind(obj) === obj.
Copy the code
3-2.Function.prototype.call.bind(Array.prototype.push)

According to 3 to 1, the Function. The prototype. Call the bind (Array) prototype) push) is equivalent to an Array. The prototype. Push. The call. So:

const arr = []
const push = Function.prototype.call.bind(Array.prototype.push)
push(arr, 'hello')

Array.prototype.push.call(arr, 'world')
console.log(arr) // ['hello', 'world']
Copy the code

4. Conclusion

Recently, the project was tested and I had some time to study the problem. I’m familiar with the use of call,apply, and bind, but the syntax of the title really hit me in the face. The main thing to understand about this is that the value of the bind binding determines who calls the call function. It just came to me in my dreams at night. ๐Ÿ˜‚