Function.prototype的apply&call(.apply.call())

Their roles are changing the function of this point

function.call(thisArg, arg1, arg2, …)
func.apply(thisArg, [argsArray])


First to a question: tell the following code produces results and the reasons for
reference stackoverflow

let myArray = Array.apply(null, {length: 10}).map(Number.call, Number);
myArray //[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

analysis:

The above formula is split into two parts:

Array.apply(null, {length: 10}) //[undefined X 10],10个undefined的数组

with

.map(Number.call, Number)

Everybody knows,

Array(10) //[,,,,,,,,,]
Array.prototype.slice.call({length: 3, 0:1, 1:2, 2:3}) //[1, 2, 3]

About the use of an array of classes, there are many

for (var i=0; i<arr.length; i++) {
  console.log(arr[i]) // logs 1 .. 2 .. 3
}
Array.prototype.forEach.call({length: 3, 0: 1, 1: 2, 2: 3}, function(x) {
  console.log(x) // 1  2  3
})

MDN:
From the start ECMAScript 5th edition, (Apply the second parameter) may be used for any kind of array of objects, a length that is as long as
the properties and range (0 ... length-1) is an integer of properties. For example NodeList can now use its own or a similar definition { 'length': 2,
'0': 'EAT', '. 1': 'bananas were'} in the form of objects.

Apply used here, is transmitted only to a class-length array, the array becomes undefined composition of 10

And then analyze the second part

.map(Number.call, Number)

The first map is its callback callback function, and the default parameters to pass three callback function; second parameter is a function of changing the internal callback this point

The Map-Array-the MDN
callback function is automatically passed three parameters: the array elements, element index, the original array itself.
arr.map new_array = var (function callback (currentValue [, index [, Array]] ) {
// for the Return Element new_array
} [, thisArg] )
Map method gives each element in the original array are sequentially called once callback function. each callback return value after execution (including undefined) combined to form a new array

Number.call equivalent to the above can be changed Function.prototype.call:

.map(function() {
    return Function.prototype.call.apply(this,arguments)
},Number)

And then change it (to replace the second parameter Number out of this):

.map(function() {
    return Number.call(arguments[0],arguments[1],arguments[2])
})

Plus the first part:

[undefined,undefined,...].map(function() {
    return Number.call(arguments[0],arguments[1],arguments[2])
})

At this point the arguments [0] is undefined, you know:

Number.call(undefined,1) //1  => Number(1)

Since Number () accepts only one parameter, i.e. arguments [2] is ignored
there

[undefined,undefined,...].map(function() {
    return Number(arguments[1]) //这里的第二个参数是数组索引(0,1,2,3.....)
})

Finally, the natural result of [0,1,2,3,4,5,6,7,8,9] came out!

If you are familiar enough js method, and these are no longer a problem!


Again a flat array of functions
function Source: Do you really understand it es6 (b)

function flatten(arr) {
    while(arr.some(res => Array.isArray(res))) {
        arr = Function.apply.call([].concat, [], arr)
    }
    return arr
}
flatten([1,[2,[4,5]]]) //[1, 2, 4, 5]

Their first wave of analysis is recommended.

analysis:

ARR-some-the MDN
arr.some (callback (Element [, index [, Array]]) [, thisArg])
This method is to iterate action to see if at least one condition is present inside the callback satisfied, i.e. the presence of returns true, otherwise Back to false
the MDN the concat-ARR-
var = new_array old_array.concat (VALUE1 [, value2 [, ... [, valueN]]])
were combined 2+ array, without changing the original array, a new array returns

Extracting key part

// 如果arr成员中存在数组,就一直执行while内部代码块
while(arr.some(res => Array.isArray(res))) {
   arr = Function.apply.call([].concat, [], arr)
}

For arr = Function.apply.call ([]. Concat , [], arr) be simplified

arr = [].concat.apply([], arr)
//为了便于理解再变一下
arr = Array.prototype.concat.apply([],arr)
//在变一下,结合上面实例
arr = [].cancat(arr[0],arr[1]) // arr[0]代表的是1+个arr的非数组类型成员,
//arr[1]则代表的是1+个arr的数组类型成员

When there is an array arr members, will continue concat,
make a small demonstration:

Array.prototype.concat.apply([],[1,[2,[3,4]]]) //[1, 2, Array(2)]
var step1 = Array.prototype.concat.apply([],[1,[2,[3,4]]])
step1 //[1, 2, [3, 4]]
var step2 = Array.prototype.concat.apply([],s1) 
step2 // [1, 2, 3, 4]

The following is the use of two properties

//1
[].concat(1,[1,2]) // [1,1,2]
//2
function f(){ this.name = 'xx'; }
f.apply(thisArg,arr) => f(arr[0],arr[1],...) { thisArg.name = 'xx'};

Understand the wrong places look Tell me what you have educated us

Do you like Skittles? I have a giraffe, you can squeeze you!

Published 15 original articles · won praise 3 · Views 3436

Guess you like

Origin blog.csdn.net/qq_39370934/article/details/103633484