preface

Popular science JavaScript, uncover the mystery of JavaScript, directly hit the soul of JavaScript. This series is for anyone.

The content of this article is as follows:

  1. Normalize the array.
  2. Arrays and array containers.
  3. The Array API is described in ECMAScript.
  4. If you want to use Array and you don’t want to learn the API approach.
  5. Extensions to the Array API beyond the standard specification.
  6. Processing and optimization of arrays by the V8 engine.
  7. The nature of data.

Array is the only complex data structure in JavaScript except Object, so it is necessary to master it thoroughly.

The original purpose of this article is to explain arrays and their functions, all apis, and convenient uses in JavaScript. Eventually, you can learn the mastery of the myriad uses and find the most correct one, making the Array operation handy.

As of the end of 2019, these are the latest ECMAScript specification, Array for JavaScript version v8, Array for C++ version v8, and the v8 Array runtime.

Tip: Due to the length of the article, I don’t think you’ll be able to read it all at once. So I suggest you collect first. If you encounter something you don’t understand or don’t want to see, you can fast forward or watch it selectively.

Standard array: Soul four asks – asks from the source of the array

The best way to learn something is to keep asking questions, and through the exploration of the questions, step by step, clear the fog and find the truth.

Above this sentence is written by teacher qian, does not have authority. So Teacher Qian first put forward a question, to prove that this view is correct.

How important are questions? That’s a problem. Here teacher Qian draws lessons from the famous words of several great gods to explain this problem:

  1. Creation begins with problems, problems will be thinking, thinking, to solve the problem, to find the possibility of independent thinking. – tao xingzhi

  2. Asking the right questions often solves more than half the problems. – Heisenberg

  3. The wisdom of life probably lies in asking why. — Balzac

  4. The first sign of an educated mind is an ability to ask questions. — Plekhanov

  5. A wise man always asks questions. — Famous programmer Teacher Qian

  6. He who is good at asking questions, such as attacking a tree, changes first, and then his program. — The Book of Rites · Xueji

  7. A good question is abundant, self – use is small. — The patent of cobras in the Book of Shang

  8. Sensitive and eager to learn, never hesitate to ask. — “The Analects of Confucius · Gongye Chang”

  9. A gentleman’s learning will be good to ask, ask and learn, also coincidental. Not to learn, not to doubt; There is no knowledge without asking. – liu open

  10. The question of knowledge is a scientific one, and there is no room for hypocrisy or pride. What is needed is the opposite — honesty and humility. – chairman MAO

Ok, teacher Qian sorted out ten reasons why questions are important, even the great founding leader Chairman MAO liked questions, very good. But this is a program article, not a catchphrase article, so please accept it. It is enough to understand that learning with problems is very efficient. Now let’s get to the point.

1. What is an array?

Now let’s ask the first formal question, what is an array?

It seems like a simple question, but is it really? If you don’t agree, you can say your answer first, and then after reading this article, to compare, and the original answer is consistent.

Here’s what The Wikipedia says about arrays:

Array data Structure (Array) is a data structure composed of a collection of elements of the same type, allocated a contiguous block of memory for storage. The index of the element can be used to calculate the corresponding storage address of the element.

From this very official explanation, Teacher Qian found several key points: same type of element, continuous memory, index.

Standard array, is the mandatory character and the above three conditions. There is another condition, which is not shown on the wiki, which is fixed size.

Array design, originally from the C language. In the later programming language, most of the array design emulates THE C language. Such as C++, Java, Go and so on.

From here on out, Teacher Qian is going to overturn your traditional idea of JavaScript arrays. Only overturn, can reverse verification. Only when broken can a broken mirror be made whole.

2. Why do arrays have types?

Let’s start with Java’s standard array. Why use Java as an example? Because there is no “standard array” in JavaScript.

int arr[] = new int[3]; /* Create an int array of length 3
arr[0] = 1; // Assign a value to the index 0
arr[1] = 2; // Assign a value to index 1
arr[2] = 3; // Assign a value to the index 2
Copy the code

So let’s do a little bit of what we normally do in JavaScript in Java.

arr[2] = "3"; // error: incompatible types: String cannot be converted to int
Copy the code

Look, Java has an error! An array of type int is not compatible with String elements.

If you’ve used JavaScript all your life and haven’t used other strongly typed programming languages, this is pretty amazing. How can arrays have types? Hurry up with the second question: Why do arrays have types?

Yes, arrays have types, and arrays have types and there’s a reason, and we’ll talk about why arrays have types later.

3. Why can’t the array length be changed?

Let’s do one more routine thing with JavaScript.

arr[3] = 1;// Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
Copy the code

Java unexpectedly error again! If you use JavaScript all the time, you might be shocked to see this. The index exceeds the maximum limit of the array.

This is another problem: once the length of an array is determined, it does not change.

Teacher Qian put forward the third question for you: why can’t the length of the array be changed?

Now, when you look at this, you’re thinking, well, with all the limitations of a standard array, it’s a little cumbersome to use, right?

4. Why do array indices start at 0?

Finally, Teacher Qian added a question that has become so common that it has been ignored: why do the indices of arrays start at 0?

To solve time

Why do arrays have types?

Because the array addressing formula is: array[I]Address = headAddress + I * dataTypeSize

What is an addressing formula?

Addressing mode is the processor according to the address information given in the instruction to find a valid address, is to determine the data address of this instruction and the next instruction to be executed address method.

So if I translate that, that’s how you find this variable in the memory block.

There are some computer principles and data structure and algorithm knowledge involved here, because the main content of this article is to explain the JavaScript Array knowledge, so Teacher Qian will not expand on these issues. But consider that a lot of people are not trained, or not trained to study computer principles seriously. Qian teacher or a little bit about addressing is what, what is used.

First of all, what is a memory address? The memory address looks like this: 0x12345678. In programming languages, the variables we create are stored in memory, which you can think of as a hash, or as object in ECMAScript, where 0x12345678 is key, and the name of the variable you create and the value of the variable are value. And addressing is finding the memory address, taking the value out of the memory address. A JavaScript expression would look something like this: Memory[“0x12345678”].

I think I understand addressing. Let’s look at creating an array again:

To create an array, you are asking memory for a fixed size of space. How big is this space? Based on the length of the array and the data type of the array.

Take the example above. If an int is a 4-byte array of 3 bytes, you need 3*4=12 bytes of memory.

Once the application is successful, the CPU locks the space. And record a memory first address for this space. Which is the headAddress of the formula up here.

In later visits, you can use this formula to address quickly.

That explains why arrays have types.

Why can’t the length of an array be changed?

Since array memory is allocated contiguously, if the length of the array changes, the memory footprint of the array also changes. The space behind the original array space may be occupied by other values, which is also for security reasons, so it cannot be changed.

Question 4: Why do array indices start at 0?

If the subscript starts at 1, it’s not a value for human decimal logic, but for the CPU, it’s a problem. The array addressing formula should be array[I]Address = headAddress + (i-1) * dataTypeSize. This will cause the CPU to subtract one more time every time an array is processed, which is not good for performance.

You should understand that the Array type we use everyday in JavaScript is not a “standard Array.” I also understand the characteristics of normalized arrays.

Array containers: Look at ArrayLists in Java and Arrays in ECMAScript

Through the above four questions to answer, I believe you also understand the array design such difficulties. It’s a long story, but it has to be.

An array container that shields details

A lot of people would be driven crazy if they kept programming with all these constraints on arrays. So clever programmers invented an array container that masked the underlying array operations.

For example, in Java, ArrayList is a highly visible example. The same is true of Array types in ECMAScript.

What are the benefits of this type of container?

So let’s do it and we can experience it.

Take Java again. Why use Java as an example? Because it’s only through comparison that you can think.

ArrayList arr = new ArrayList(1);// Create an array of initial length 1
arr.add(1);// Add 1 data
arr.add("2");// Add one more String
System.out.println(arr);// No problem, normal output [1, 2]
Copy the code

You can see that Java’s ArrayList solves two important problems.

1. Can store different types of data.

2. The capacity can be automatically expanded.

So how does it work? This, though, is outside the scope of this article. But the teacher still can’t help but say briefly.

1. How to store different types of data?

In both JavaScript and Java, the basic memory is divided into the Head memory and the Stack memory. Because of the basic data type, (sorry, interrupt, teacher qian here to ask a question? How many basic data types does ECMAScript have in 2019?) It’s all stored in stack memory. Why do we store it in stack memory? That’s another good question. You can take a guess. Since basic data types are fixed values, since values are fixed, the size is also fixed. How many bytes does a 3-character String variable take in ECMAScript? You see, the problem is everywhere, just see you have the eyes to find the problem. ** This is a small Easter egg. Before ECMAScript2015, ECMAScript5.0 used Unicode encoding, Chinese characters and English characters were 2 bytes in size. So the answer to the above question is 2*3=6 bytes. But after ECMAScript6, the answer is different. Because the encoding changed. It changed to UTF8. Here teacher Qian again ask a question, what is the difference between Unicode and UTF8? Hey hey, is it going to crash? Utf8 is encoded in lengths ranging from 1 to 4 bytes. Because foreigners find that most of the websites in the world are in English language, while other languages (in foreigners’ eyes, all other languages are collectively referred to as other languages) account for very little. So in UTF8, English characters take up only one byte, while other languages, like Chinese, take up three bytes. So the above question also lacks a condition, also has to be clear which language three characters are in order to give the correct answer. So let’s get back to the heap and the stack. Since the size of the basic data types is fixed, it is good to know the total size of the array on the stack, so you can apply for contiguously large chunks of memory. What does ECMAScript do when storing variables of reference types? If you’re smart enough to guess that, it’s stored in the heap. To be exact, the variable data is stored in the heap memory, while the stack memory still stores one thing, which is the heap memory memory pointer, also known as a reference. So that explains how array containers store different types of data.

I won’t expand on the details of heap memory and stack memory.

If you want to learn more about this section, I recommend you check out Chapter 4 of Advanced Programming in JavaScript, Version 3.

Stack memory is not a concept that can be isolated. If you want to learn it thoroughly, you need to learn it systematically to really understand it. For students with poor foundation, it is recommended to read “Deep Understanding of computer Systems (original book, 3rd edition)”. The book received a high score of 9.8 on Douban. But in reality, it is not a “deep” book in the traditional sense. It is a book that explains the whole context of “the bottom of the computer”. So it’s a very broad book, and it’s perfect for perfecting one’s computer knowledge.

2. How to implement automatic capacity expansion?

The ArrayList is constructed with no arguments and by default creates an array of size 10. Each time an element is added, it checks to see if there is enough capacity, and if not, internally creates a new array that is 1.5 times the size of the original array. Then move all the data from the original array to the new array. If the capacity of the new array is still insufficient, an array of characters and the required capacity is created directly.

There is no big problem with this, but the biggest problem is that performance will suffer. The other problem, which is not related to JavaScript, is thread-safety. Because of the creation of new arrays, the process of migrating data takes some time. Java is a multithreaded language, and if another thread accesses the ArrayList in the middle of the process, there will be a problem.

Why explain Java’s ArrayList? Because the teacher has only seen ArrayList implementation source code, very embarrassed. For those of you who haven’t seen JavaScript before, if you’re interested, check out the V8 source link I posted at the beginning of this article to see what ECMAScript does. I guess its implementation and ArrayList is the same principle, you can come back and tell the teacher, see if the teacher guessed right. Although teacher Qian has not read the implementation of V8 carefully, please do not question teacher Qian’s degree of expertise in JavaScript, nor do you guess that teacher Qian is engaged in Java. Let me emphasize here that Mr. Qian is a serious JavaScript programmer and has always used JavaScript as his first programming language. Oh no, TypeScript now.

Whether it’s Java’s JDK or ECMAScript’s V8, the bottom line is C. So qian teacher here suggest everyone: must not want to open to see C source.

To sum up: anything that doesn’t work for programmers will always be modified in one way or another. Until it’s something everyone likes. If you want to get to the bottom of something, you have to go back to the source, look at what she looked like, then look at the whole process of her makeup, plastic surgery, and finally see how she moulted into a butterfly step by step.

What is the nature of arrays in EAMCAScript?

This is one of the most common arrays in JavaScript.

let arr = [
  "h",
  9,
  true,
  null,
  undefined,
  _ => _,
  { a: "b" },
  [1, 2],
  Symbol(1),
  2n ** 1n,
  Infinity,
  NaN,
  globalThis,
  Error("hi"),
  Math.LN10,
  Date(),
  /\w+/i,
  new Map([["k1", "v1"]]),
  new Set([1, 2]),
  new DataView(new ArrayBuffer(16)),
  new Promise((resolve, reject) => {}),
];
Copy the code

A little messy, but harmless. As you can see, arrays are like huge black holes that can hold anything in ECMAScript. Variables, data of any data type, including arrays themselves. This reminds me of the game advertisements that often appear in QQ space, the classic of Mountains and seas, the kun who swallows heaven and earth and can’t swallow anything.

Why is it possible to do that?

Because, as described above, when arrays store basic types, they store values. When you store a reference type, you store a memory reference.

Arrays in ECMAScript are nothing like traditional arrays. Because it’s an object.

Because ECMAScript is a weakly typed language and has no type system constraints, variables of any type can be attached to any property. Arrays are no exception.

Adds a property to an object.

let obj = {};
obj["0"] = 1;
Copy the code

Adds an element to an array.

let arr = [];
arr["0"] = 1;
Copy the code

Value from an object.

obj["0"];
Copy the code

Value from an array.

arr["0"];
Copy the code

Another example is the following array:

["dog"."pig"."cat"];
Copy the code

Equivalent to the following objects:

{
    "0": "dog"."1": "pig"."2": "cat"."length": 3
}
Copy the code

In some ways, there is no obvious difference between an Array and an Object. Even more radically, Array and Object are essentially the same thing. (This sentence teacher qian does not assume any legal responsibility, is just casually say)

In JavaScript, you can completely think of arrays as higher-order implementations of objects.

How free is Array in JavaScript? Different types of values can be stored, and can be accessed through negative indexes, subscripts beyond the original declaration range, or even through non-numeric indexes. Array is not an Array, but it’s still called an Array, and it’s still a little bit like an Array, because Array still starts with “0”. (This is a bad joke.)

So, don’t use traditional Array concepts to define ECMAScript’s Array. Because it just looks like it.

Hard validation: The Array API in ECMAScript

All the things that should be said and not said, all the things that should be asked and not asked.

Now, let’s move on to the final part of this article and get a feel for the power of Array in all its apis.

Before Teacher Qian wrote this article, many people have written similar excellent articles, such as MDN

But teacher qian promises to be more vivid than these people, easy to understand, interesting and unique. Take you deep into… Shunt out the Array world.

Although this article appeared very late, but there is no way. Thousands of teachers believe that the waves can be slapped on the beach before the waves, hard ravaged.

The total number of Array properties and methods in the current standard specification is a whopping 36.

Let’s start by creating an array.

Create an array

The mystery of creation is like the darkness of night — it is great. Delusions of knowledge are like the things of the morning. — tagore

There are three common and standard ways to create an array.

1. Create using the literal []

let arr1 = [0.1.2];
Copy the code

2. Create using the Array constructor

let arr1 = new Array(0.1.2);
Copy the code

3. Use the built-in Array method to create an Array

let arr1 = Array(0.1.2);
Copy the code

Similarities and differences:

Methods 2 and 3 have the same effect because the this pointer is determined inside the Array implementation.

There are two ways to use new Array and Array. When you pass only one parameter, instead of creating an Array to store that value, you create an undefined element with the value of the parameter.

let arr1 = [10]; / / [10]
let arr2 = Array(10); // [undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined]
Copy the code

There are also unusual and non-standard ways to create arrays. Specific several thousand teachers have not been counted, because this is not very important. One of the most common unusual and nonstandard uses is “from.”

Access to an array

Truth is life, you should not look for it in your head. — Romain Rolland

After creating the array, let’s see how to access the array.

Accessing an array is actually quite simple, with square brackets [].

let arr1 = [0.1.2];
arr1[0]; / / 0
Copy the code

We’re used to writing a parameter of type number in square brackets, because we know that the number is the array index of the element, and the array index is a value of type number, which is normal. Arr1 [0] in the example above will change to arr1[‘0’] when actually executed. Is implicitly converted by the toString method. Why is that? Because the ECMAScript specification does. If you are interested in it, you can check it yourself. Although there is an implicit conversion process, the normal programmer would not use the quoted form directly.

Instance attributes

constructor

I have no father or mother. — The Book of Songs

In ECMAScript, almost everything except null and undefined has this attribute. Indicates who constructed the object.

This property is usually used to determine whether an object is an instance of an Array.

let arr = [];
arr.constructor === Array; // true
Copy the code

Unfortunately, this property is writable. Writable means that this method does not tell 100 percent whether an object is an instance of Array.

let arr = [];
arr.constructor = String;
arr.constructor === Array; // false
arr.constructor === String; // true
Copy the code

You can see that the arr variable, which was originally generated by Array, is changed to String as its parent by a single line of code. Proved again, Array instance, is rich is the father, have milk is the mother of the goods.

Let’s do another example.

let str = "";
str.constructor = Array;
str.constructor === Array; // false
str.constructor === String; // true
Copy the code

STR and ARR have distinct differences. STR is a filial son. His real father is his real father. It doesn’t matter if he has money.

In fact, this property can be changed for several basic types other than String, but it doesn’t work.

Why didn’t it work? Because it involves opening a box.

So here’s a question: Why can primitive types call methods and access properties?

Understand this problem, you can understand the above phenomenon. This is not Array knowledge, this is an extension of knowledge.

What’s the difference between a primitive type created by a constructor and a primitive type created by a literal?

length

Some are short and some are good

Represents the number of elements in the array.

let arr = [0.1.2];
arr.length; / / 3
Copy the code

This property seems pretty simple, there’s nothing to talk about, right?

There’s actually something I can tell you.

The greatest benefit of length is that you can delete or increase elements by changing length directly.

let arr = [0.1.2];
arr.length = 2;
console.log(arr); / / [0, 1]
arr.length = 5;
console.log(arr); // [0, 1, empty × 3]
Copy the code

If you look at this, you see empty again. What is that? You know what?

Empty is something very similar to undefined, but slightly different.

Here’s an experiment.

console.log(arr[3= = =undefined); // true
Copy the code

In this experiment, we find that empty is all equal to undefined.

But there are some differences. Take the following experiment.

arr.indexOf(undefined); // -1

arr.filter(item= > item === undefined); / / []
arr.forEach(item= > {
  console.log(item);
}); / / 1. 2
Copy the code

IndexOf, Filter, and forEach do not consider empty to be undefined. Empty is automatically ignored.

Let’s do two more experiments.

arr.includes(undefined); // true

arr.map(item= > typeof item); // ["number", "number", empty × 3]
Copy the code

But “empty” is the same as “undefined”. In map, the empty slot is automatically reserved.

It’s not that Typeof doesn’t work, it’s that the Typeof item statement, when it comes to empty, skips it and doesn’t execute.

To prove this, let’s experiment with the universal Typeof operator alone.

console.log(typeof arr[3]); // undefined
Copy the code

What’s going on here? In ECMAScript6, empty is explicitly defined as undefined and should be treated as such in any case. Teacher Qian went to the V8 source code, and indeed found a description of empty in the V8 source code, it turned out to be an empty object reference.

What type should an empty object reference be in ECMAScript? There are only a few types of ECMAScript, so it doesn’t fit any of them.

Undefined, the awkward data type, has somehow become the villain of Empty.

methods

from

A scholar can not not be resolute, a heavy task and a long way to go

Since ECMAScript1, there has been a headache (of course, there is more than one headache, and when I say one, I don’t mean only one, which is important to note). , ECMAScript is full of array-like objects. They’re like arrays, but they’re not arrays. The most typical examples are the Arguments object and getElementsByTagName.

To solve this problem, many libraries have their own solutions. JQuery, the famous archaic JavaScript library, has a method called makeArray.

With the rapid evolution of science and technology, through the efforts of countless JavaScript enthusiasts, the pursuit of dedication, experienced more than 20 years of changes in the sea and fields, white clouds and blue dogs. ECMAScript is finally here with its own super API. With this API, ECMAScript no longer needs third-party solutions like makeArray. ECMAScript stands up! Speaking of this, Master Qian can’t help but think of those great gods who shed their blood for the freedom, openness, expansion and integration of ECMAScript. It was they who stepped forward to save the people from suffering when ECMAScript was being humiliated. During the development of ECMAScript, The ecmascripters dared to face their lives and face their blood. In the face of Java, C, C++, and even PHP, everyone said “isn’t it just a scripting language?” In the insult, we with burning passion and blood condensed into the spirit of the torch, ignited the future.

That’s far from it. Let’s take it back. After all, let’s learn more about the use of “from”.

Function: Creates a new array from an array-like object or iterable.

Array.from(arrayLike[, mapFn[, thisArg]])

Parameters:

  • ArrayLike: A pseudo-array object or iterable that you want to convert into an array.

  • MapFn ** (optional) : If this parameter is specified, this callback is performed for each element in the new array.

  • **thisArg ** (optional) : this object when the callback function mapFn is executed.

Return value: new array instance.

Supports the String, Set, Map, and arguments types.

It also supports creation through functions.

/ / a String Array
let arr1 = Array.from("123"); / / / "1", "2", "3"]
/ / Set the Array
let arr2 = Array.from(new Set([1.2.3])); / / [1, 2, 3]
/ / the Map Array
let arr3 = Array.from(
  new Map([[1.1],
    [2.2],
    [3.3]]));// [[1, 1], [2, 2], [3, 3]]
/ / MapKey Array
let arr4 = Array.from(
  new Map([[1.1],
    [2.2],
    [3.3],
  ]).keys()
); / / [1, 2, 3]
/ / MapValue Array
let arr5 = Array.from(
  new Map([[1.1],
    [2.2],
    [3.3],
  ]).values()
); / / [1, 2, 3]
/ / the arguments Array
function fn() {
  return Array.from(arguments);
}
fn(1.2.3); / / [1, 2, 3]
Copy the code

In addition to the role of transformation, programmers who like to explore have found several other magical uses.

1. Used to create arrays.

let arr = Array.from({ length: 3 });
console.log(arr); // [undefined, undefined, undefined]
Copy the code

The from method is nice. It doesn’t create three empty objects. It seems that the ECMAScript6 specification works fine, at least Chrome listens to it.

You can also add some logic here, such as generating an array of numbers in a range.

let arr = Array.from({ length: 3 }, (item, index) => index);
console.log(arr); / / [0, 1, 2]
Copy the code

2. Shallow copy arrays.

let arr = [1.2.3];
let arr2 = Array.from(arr);
Copy the code

3. Deep copy arrays.

Based on shallow copy Array, combined with Array. IsArray to achieve. The principle is simple.

function arrayDeepClone(arr) {
  return Array.isArray(arr) ? Array.from(arr, arrayDeepClone()) : arr;
}
Copy the code

There are several ways to copy arrays in depth and depth in ECMAScript, what are their pros and cons, and what application scenarios are they suitable for?

In addition to these methods, there are many other scenarios of the wonderful use, here is not one of the examples. In short, the API is very flexible, and those who like to explore can try it out for themselves.

isArray

The false is true when it is true, and the true is true when it is false.

Function: Determines whether a variable is an array object.

Grammar: Array. IsArray (obj)

Parameters:

  • Obj: indicates the value to be detected.

Return value: true if the value is Array; Otherwise, false.

Returns a Boolean value.

let arr = [];
Array.isArray(arr); // true
Copy the code

There are two other common ways to determine whether a variable is an array.

1. Use instanceof.

let arr = [];
arr instanceof Array; // true
Copy the code

The principle of Instanceof is implemented through the prototype chain. That is to determine whether there is a right prototype in the prototype chain of the left object. How do I implement Instanceof manually?

2. Use constructor.

let arr = [];
arr2.constructor === Array; // true
Copy the code

The constructor property holds the constructor when the instance is created, but this property can be modified.

3. The use of the Object. The prototype. ToString. Call

let arr = [];
Object.prototype.toString.call(arr); // "[object Array]"
Copy the code

Object. The prototype. ToString. Call () built-in objects are often used to judge ECMAScript. But this method can be overridden.

Each of these approaches has its drawbacks. However, it is highly recommended to use Array.isArray directly. Because in iFrame, instanceof and Constructor fail. And the Object. The prototype. ToString too trival again this way.

The return value of these methods can be tampered with. So don’t trust your eyes when sometimes the code doesn’t live up to expectations. Use your head.

The following is the method of tampering, but do not idle nothing in your own project to change oh, save the leader K.

let arr = [];
Array.isArray = (a)= > false;
Array.isArray(arr); // false

let arr2 = [];
arr2.__proto__ = Object;
arr2 instanceof Array; // false

let arr3 = [];
arr3.constructor = String;
arr3.constructor === Array; // false

let arr4 = [];
Object.prototype.toString = (a)= > "object";
Object.prototype.toString.call(arr4); // "object"
Copy the code

of

A miss is as good as a mile. — Book of Han

Here’s another bad thing about the beginning of Array design, because when you create an Array using new Array or Array, it behaves differently depending on the number and type of parameters. You will never be able to use new Array to create an Array with only one number. To exaggerate, there is only one purely practical reason for using the “of” method: to create an array with only one number. ** The benefit of doing this is to unify the behavior of creating arrays.

Function: Used to create a new array instance with a variable number of arguments, regardless of the number or type of arguments.

Of (element0[, element1[,…[, elementN]]])

Return value: the newly created array instance.

let arr = Array.of(10); / / [10]
Copy the code

This is used to distinguish between an Array passing a parameter of type number. I’m going to create an array where the element is equal to the first argument.

It’s a good idea to use the of method instead of the Array constructor when you have to use it to create an Array.

Instance modifier method

It changes the value of the array itself.

copyWithin

What you lose, you gain. — Book of the Later Han dynasty

An API with a very low presence and no application scenarios to be found is called overdesign.

Function: shallowly copies a part of an array to another position in the array and returns it without changing the length of the array.

Syntax: arr.copyWithin(target[, start[, end]])

Parameters:

  • Target: the subscript of the target position to move to
  • Start: The start index is optional. The default value is 0.
  • end: Optional, terminating index (excluding this element), default isarr.length.

Return value: modified array.

let arr1 = [0.1.2.3.4];
let result = arr1.copyWithin(1.2.4); // Cut off the elements from index 2 to 4 and insert them at index 1
console.log(arr1); // [0, 2, 3, 3, 4]
console.log(result); // [0, 2, 3, 3, 4]
Copy the code

fill

Short step, not even thousands of miles; Do not accumulate small streams, beyond into rivers and seas. — Xunzi

Presence is the same as copyWithin.

Function: Replace the values of all elements in a specified range of an array with a fixed value.

Syntax: arr.fill(value[, start[, end]])

Parameters:

  • Value: The value used to populate the array elements.
  • Start: The start index is optional. The default value is 0.
  • end: Optional, terminating index (excluding this element), default isarr.length.

Return value: modified array.

let arr = [0.1.2.3];
let result = arr.fill(1.2.3);
console.log(arr); // [0, 1, 1, 3]
console.log(result); // [0, 1, 1, 3]
Copy the code

pop

Gentlemen love fortune, in a proper way — The Analects of Confucius

Pop was inspired by stacks. It’s actually one of the standard operations on the stack, and it’s the most basic operation. Pop and Push are brothers who love each other and kill each other.

Removes the last element from an array and returns it.

Grammar: arr. Pop ()

Return value: the element removed from the array (undefined if the array is empty).

const arr1 = [1.2.3];
const result = arr1.pop();
console.log(arr1); / / [1, 2]
console.log(result); / / [1, 2]
Copy the code

As the oldest and most basic operation, pop doesn’t have a lot of bells and whistles.

push

All rivers run into the sea; There is no desire but a precipice. – Lin zexu

As Pop’s twin brother, IT reminds me of the saying that pop should take away what is pushed.

Adds an element to the end of an array and returns the length of the array after the operation.

Parameter: the element to be added to the end of the array.

Arr. Push (element1,… , elementN)

Return value: the new value of the Length attribute.

let arr = [1.2.3];
let result = arr.push(5.6.7);
console.log(arr); // [1, 2, 3, 5, 6, 7]
console.log(result); / / 4
Copy the code

Pop’s anti-operation function, also an old API, is very simple to operate.

reverse

Three thousand fame dust and soil, eight thousand li cloud and month. – yue fei

Effect: Inverts the order of the elements in an array, i.e. the first element becomes the last, and the last element becomes the first.

Grammar: arr. Reverse ()

Return value: modified array.

const arr = [1.2.3];
const result = arr.reverse();
console.log(arr); / / [3, 2, 1)
console.log(result); / / [3, 2, 1)
Copy the code

Reverse can be used in conjunction with a number of other apis to reverse strings.

let str = "hello,world!";
str
  .split()
  .reverse("")
  .join(""); / / "! dlrow,olleh"
Copy the code

shift

I would not be the person I am today if I deleted a single moment of my life. — Ryunosuke Akutagawa

Shift and pop do the same thing, except that pop removes the last element of the array.

Removes the first element from an array and returns its value. This method changes the length of the array.

Grammar: arr. The shift ()

Return value: the element removed from the array; Return undefined if the array is empty.

const arr1 = [1.2.3];
const result = arr1.shift();
console.log(arr1); / / [2, 3]
console.log(result); / / 1
Copy the code

sort

Man is the result of his own actions and nothing else. – jean-paul Sartre

Function: Use custom algorithms to sort the elements of an array. The default sort order is built when you convert elements to strings and then compare them to a sequence of UTF-16 code unit values

Grammar: arr. Sort ([compareFunction])

Parameters:

CompareFunction ([firstEl, secondEl]) : Specifies the functions that are arranged in a certain order, which is optional. If omitted, the elements are sorted by the Unicode loci of each character in the string to which they are converted.

FirstEl: The first element used for comparison.

SecondEl: The second element for comparison.

Return value: sorted array.

const arr1 = [1.9.9.8.0.8.0.7];
const result = arr1.sort((x, y) = > x - y);
console.log(arr1); // [0, 0, 1, 7, 8, 8, 9, 9]
console.log(result); // [0, 0, 1, 7, 8, 8, 9, 9]
Copy the code

Sorting performance depends on the custom functions. And running the engine. Teacher Qian studied the reality of the underlying engine, but found that each engine implementation is different, so the same code, running on different platforms, the speed will be different.

splice

Will often run counter to the fate, determined in the end will be all down. — William Shakespeare

Function: Modifies an array by removing or replacing existing elements or adding new elements in place, and returns the modified contents as an array. This method changes the array.

Splice (start[, deleteCount[, item1[, item2[,…]]]])

Parameters:

Start: Specifies the start position of the modification (counting from 0). If the length of the array is exceeded, the contents are added from the end of the array. If negative, it indicates the number of digits starting from the end of the array (counting from -1, which means -n is the reciprocal NTH element and is equivalent to array.length-n); If the absolute value of a negative number is greater than the length of the array, it starts at the 0th bit.

DeleteCount: Optional integer indicating the number of array elements to remove. If deleteCount is greater than the total number of elements after start, then all elements after start will be deleted (including the start bit). If deleteCount is omitted or its value is greater than or equal to array.length-start (that is, if it is greater than or equal to the number of elements after start), then all elements of the array after start are deleted. If deleteCount is 0 or negative, the element is not removed. In this case, at least one new element should be added.

item1, item2, … : Optional, the elements to add to the array start at the start position. If not specified, splice() will remove only the array elements.

“Splice” means to cut, which is a fraction of the difference between the accessor method slice, but not a fraction of the difference. Slice means to slice. A lot of people confuse the two. I saw a foreigner say a good way to tell memory apart. The P from Splice means Produces Side Effects. ECMAScript has more than one pair of similarly named but distinct apis, such as substr and Substring strings.

Splice is used in a variety of ways. But it boils down to four operations.

Cutting operations

Just focus on the first parameter. When you pass only one argument, it means truncation. Splice can truncate arrays just like length.

let array = [0.1.2.3];
array.splice(3);
Array. Length = 3;
Copy the code

The insert

Just focus on the first argument and the third argument. The first parameter indicates where to start the insertion, and the third parameter indicates what element to insert. The second parameter is set to 0 to indicate the insert operation.

let array = [0.1.2.3];
array.splice(1.0."1"); // Insert element '1' from subscript 1
console.log(array); // [0, "1", 1, 2, 3]
Copy the code

Delete operation

Just focus on the first argument and the second argument. The first parameter means delete from there, and the second parameter means delete several elements.

let array = [0.1.2.3];
array.splice(1.1); // Delete one element from the subscript 1
console.log(array); / / [0, 2, 3]
Copy the code

Delete and insert operations

This operation requires attention to all parameters, as mentioned earlier.

const arr = [1.2.3];
const result = arr.splice(1.2.10.11); // Remove 2 elements from 1 and add elements 10 and 11
console.log(arr); / / [1, 10, 11]
console.log(result); / / [2, 3]
Copy the code

Note that Splice also supports negative subscripts.

let array = [0.1.2.3];
array.splice(2 -.1.1.2.3); // [0, 1, 1, 2, 3, 3]
Copy the code

unshift

Ask canal which get clear so much, for the source of living water. – zhu xi

Adds one or more elements to the beginning of an array and returns the new length of the array.

Syntax: arr. Unshift (element1,… , elementN)

Argument list: The element or elements to add to the beginning of the array.

Return value: Returns the value of the length attribute of the added array.

There’s nothing to talk about. Shift’s the opposite of push.

const arr = [1.2.3];
const result = arr.unshift(5);
console.log(arr); // [5, 1, 2, 3]
console.log(result); / / 4
Copy the code

Arraylike object

An object that has the characteristics of an array, an array-like object, is also called an ArrayLike.

From part 2, the Array container section, we learned that in JavaScript, arrays and array-like objects operate very similarly. In fact, what’s even more interesting is that we can not only treat objects as arrays, we can even treat objects as arrays.

let obj = {
  push: function(el) {
    return [].push.call(this, el); }}; obj.push(2);
console.log(obj);
/** [object Object] { 0: 2, length: 1, push: function(el){ return [].push.call(this, el); }} * * /
Copy the code

As you can see, push automatically adds a 0 attribute and a length attribute to the object.

Let’s do another experiment.

let obj = {
  0: 0.push: function(el) {
    return [].push.call(this, el); }}; obj.push(2);
console.log(obj);
Copy the code

When we find push, the original attribute 0 is replaced by 2.

This is the rule for push: the push method determines where to start inserting the given value based on the length attribute. If length cannot be converted to a numeric value, the element is inserted with an index of 0, including if length does not exist. Length is created when it does not exist.

Now let’s see if length exists.

let obj = {
  0: 0.length: 10.push: function(el) {
    return [].push.call(this, el); }}; obj.push(2);
console.log(obj);
/** [object Object] { 0: 0, 10: 2, length: 11, push: function(el) { return [].push.call(this, el); }} * * /
Copy the code

You can see that the length attribute performs the +1 operation, and it thinks that there are now 10 elements in the array, so the new 2 will be the 11th element, with the subscript 10. Push is so stupid, yes, he is so stupid.

His brother, Pop, has the same behavior as push. I won’t go into the demo here, but you can try it yourself with an object extension.

This behavior is called duck type. So what is a duck type?

Duck typing is a style of dynamic typing in programming. In this style, the valid semantics of an object are determined not by inheriting from a particular class or implementing a particular interface, but by the “current collection of methods and properties.” The name of this concept is derived from the duck test (see section “History” below) proposed by James Whitcomb Riley. The duck Test can be described as follows:

“When you see a bird that walks like a duck, swims like a duck and quacks like a duck, that bird is called a duck.”

That is, in ECMAScript, objects that look like arrays can be manipulated by array methods. This is not limited to just pup and push, there are many other methods that can be applied to this set of rules.

Instance access method

It doesn’t change the value of the array itself, it returns the new value.

concat

Building, not a wood also; The embellishment of the sea is not a first-class return. — Annals of Kingdoms in the Eastern Zhou Dynasty

Function: Merges two or more arrays. This method does not change the existing array, but returns a new array.

Syntax: var new_array = old_array.concat(value1[, value2[,…[, valueN]]])

Parameters: value*N* This parameter is optional

Concatenate arrays and/or values into a new array. If the valueN argument is omitted, concat returns a shallow copy of the existing array it called.

Returned value: new Array instance.

const arr1 = [1.2.3];
const arr2 = [4.5.6];
const result = arr1.concat(arr2, 7."8"[9]);
console.log(result); // [1, 2, 3, 4, 5, 6, 7, "8", [9]]
Copy the code

There are two main points to note in concat. First, you can concatenate everything, not necessarily arrays, as shown in the example above.

The second point is that the operation of concat is a shallow copy, as follows.

const arr1 = [1.2.3];
const obj = { k1: "v1" };
const arr2 = [[4]].const result = arr1.concat(obj, arr2);
console.log(result); // [1, 2, 3,{ k1: "v1" }, [4]]
obj.k2 = "v2";
arr2[0].push(5);
console.log(result); // [1, 2, 3,{ k1: "v1", k2: "v2" }, [4, 5]]
Copy the code

includes

Will there be life without breath, continuity without perfect, and existence without pure? — Song Yingxing, “Talking about heaven, Day and Three”

Returns true if an array contains a specified value, false if it does not.

Syntax: arr.includes(valueToFind[, fromIndex])

Parameters:

ValueToFind: Optional value of the element to be found. If not, return false.

FromIndex: This parameter is optional. Start the search for valueToFind from the fromIndex index. If the value is negative, the search starts with the index of array. Length + fromIndex in ascending order (even if the search starts with the absolute value of fromIndex, and then searches backwards). The default is 0.

Return value: A Boolean value indicating whether the element exists.

const arr1 = [1.2.3];
const result = arr1.includes(1);
console.log(result); // true
const result2 = arr1.includes(22);
console.log(result2); // false
Copy the code

Note: You cannot determine the reference type of a literal, only the underlying type and reference.

const t = [1];
const arr1 = [t, 2.3];
const result = arr1.includes(t);
console.log(result); // true
const result2 = arr1.includes([1]);
console.log(result2); // false
Copy the code

Includes was created in EMAScript6. Back in EMAScript5, people liked to use indexOf equal to -1 to determine whether an element was in an array. There used to be a third-party API called Contains that did something similar. So if it’s a new API and it’s doing something similar to an existing API, there must be a reason. What’s the reason?

Let’s start with a general operation.

const arr = [1.2.3];
console.log(arr.indexOf(2)! = =- 1); // true
console.log(arr.includes(2)); // true
Copy the code

Seems to be all right?

So let’s do one more unusual operation.

const arr = [NaN];
console.log(arr.indexOf(NaN)! = =- 1); // false
console.log(arr.includes(NaN)); // true
Copy the code

There you go! IndexOf does not match NaN properly because NaN === NaN results in False in ECMAScript.

Let’s do another example.

const arr = [, , , ,];
console.log(arr.indexOf(undefined)! = =- 1); // false
console.log(arr.includes(undefined)); // true
Copy the code

These are probably the biggest differences between Includes and indexOf.

join

When people mo xiaochi water, shallow place just as well as wolong. — Dou Xiang “Gift of Fu Zai in drunk”

Concatenate all the elements of an array into a string and return the string. If the array has only one item, the item is returned without a delimiter.

Grammar: arr. Join ([the separator])

Parameters:

Separator: Optional, specifies a string to separate each element of the array. Convert the delimiter to a string if needed. If this is the default, array elements are separated by commas (,). If separator is an empty string (“”), then there are no characters between all the elements.

Return value: a string of all array elements concatenated. If arr.length is 0, an empty string is returned.

const arr = [1.2.3];
const result = arr.join();
console.log(result); / / "1, 2, 3"
Copy the code

Join and split of a string have almost the opposite effect.

One thing to notice when using join is that it calls each element toString before concatenating it. Elements like an empty array, when converted to a string, are “”, so concatenation is nonexistent.

let arr = ["h".9.true.null, [] {}];let result = arr.join("|");
console.log(result); // "h|9|true|||[object Object]"
Copy the code

Of course, you can actively override its toString method, and the result will be different.

let arr = ["h".9.true.null, [] {}]; [].__proto__.toString =function() {
  return "Array";
};
let result = arr.join("|");
console.log(result); // "h|9|true||Array|[object Object]"
Copy the code

An exception occurs if there are elements in the array that could be converted to strings. Such as the Symbol.

let arr = ["h".9.true.null.Symbol(1)];
arr.join("|"); // TypeError: Cannot convert a Symbol value to a string
Copy the code

slice

Dare to waste even an hour of time, he did not know how to cherish all the value of life. – Charles Darwin

Function: Cut a segment from an array to form a new array. Take two arguments, the first is the index of the start element and the second is the index of the end element (excluding this element).

Syntax: arr. Slice ([begin[, end]])

Parameters:

Begin: Indicates the index at the start of extraction. The default value is 0.

End: Optional. Default is array length. Extract the index at the end. (Include begin, do not include end)

Return value: a new array containing the extracted elements.

const arr1 = [1.2.3];
const result = arr1.slice(1.2); // Cut from index 1 to index 2
console.log(result); / / [2]
Copy the code

Special usage:

Slice () can shallow copy arrays.

const result = arr1.slice();
Copy the code

toSource

Books to time square hate less, you never know till you have gone through. – lu you

ToSource is not part of the standard API. It is only used in Firefox and is not recommended. You can pass it.

Function: Returns a string representing the source code of the array.

Grammar: array. ToSource ()

const array = [1.2.3];
array.toSource(); / / "[1, 2, 3]." "
Copy the code

toString

Whales fall to the bottom of the sea and feed all beings in the dark world for 15 years. — Gary Snyder

Function: Returns a string representing the specified array and its elements.

Grammar: arr. ToString ()

Return value: a string representing the specified array and its elements.

ToString overrides the toString method of Object, returning a string containing each array element separated by a comma. When an array is treated as a text value or concatenated, its toString method is automatically called.

If you want to manually convert an array to a string, you are advised to use join because it is more flexible.

const arr1 = [1.2.3];
const result = arr1.toString();
console.log(result); / / "1, 2, 3"
Copy the code

toLocaleString

The movement of the roc is not the light of a feather. Steed’s speed is not a single effort. — “On The Explanation of Difficulties”

Grammar: arr. ToLocaleString ([locales, [options]]).

Parameters:

Locales: Optional, a string or array of strings with BCP 47 language tags.

Options: optional, a configurable attributes of objects, for digital Number. The prototype. ToLocaleString (), for the Date Date. The prototype. ToLocaleString ().

Return value: a string representing an array element.

Now that toStrings exist, what problem is toLocaleString designed to solve?

In addition to Array, this API exists for dates, numbers, and Objects.

The main difference between toLocaleString and toString is the argument to toLocaleString, which translates the element into the human language of the country. Like the number one million. The Spanish are represented as 1.000.000 and the British as 1,000,000. And the date is also the same, such as the Chinese mainland with year year/month/day morning or afternoon 12 hours system, while most foreign days/month/year 24 hours system minutes and seconds.

const arr1 = [1000000.new Date()];
const resultENGB = arr1.toLocaleString("en-GB");
const resultESES = arr1.toLocaleString("es-ES");
const resultAREG = arr1.toLocaleString("ar-EG");
const resultZHCN = arr1.toLocaleString("zh-CN");
console.log(resultENGB); / / 1000000/12/2019, 23:40:39 ""
console.log(resultESES); / / "1.000.000, 29/12/2019 23:40:39"
console.log(resultAREG); / / ١ ٬ ٠ ٠ ٠ ٬ ٠ ٠ ٠, ٢ ٩ ‏ / ١ ٢ ‏ / ٢ ٠ ١ ٩ ١ ١ : ٤ ١ : ٣ ١ م
console.log(resultZHCN); // "1,000,000,2019/12/29 下午11:40:39"
Copy the code

From the above example, it can be concluded that the fundamental purpose of toLocaleString is to ensure that the browser of users in multiple countries is consistent with their own custom. Because the Chinese can’t read Arabic numbers and dates at all, the Arabs can’t read Chinese dates as easily.

The second parameter is so powerful that it is usually used to show the currency and can be customized after the transformation.

const arr1 = [1000000.new Date()];
const resultGBP = arr1.toLocaleString("en-GB", {
  style: "currency".currency: "GBP"});const resultCNY = arr1.toLocaleString("zh-CN", {
  style: "currency".currency: "CNY"});console.log(resultGBP); / / "£1000000.00, 29/12/2019 23:51:18"
console.log(resultCNY); // "¥1,000,000.00,2019/12/29 11:51:18"
Copy the code

As you can see, once you set the code for the bill, you can convert the numbers into the bill. It should be noted that the code of RMB is CNY, not RMB. Okay, just kidding.

In fact, when you call toLocaleString for an Array, you automatically call toLocaleString for each element. As mentioned earlier, only arrays, dates, numbers, and objects have this API, so what about other types without this API? Call toString.

indexOf

Some birds are not meant to be caged, their feathers are just too bright. — The Shawshank Redemption

Function: returns the first index in the array where a given element can be found, or -1 if it does not exist.

Syntax: arr. IndexOf (searchElement[, fromIndex])

Parameters:

SearchElement: The element to look for.

FromIndex: Optional. Start the search. If the index is greater than or equal to the length of the array, it means that the array is not looked up, and -1 is returned. If the index value provided in the argument is a negative value, it is treated as a cancellation at the end of the array, i.e. -1 means the search starts with the last element, -2 means the search starts with the penultimate element, and so on. Note: If the index value provided in the argument is a negative value, the lookup order is not changed. The lookup order is still the front – to – back lookup of the array. If the offset index is still less than 0, the entire array will be queried. The default value is 0.

In the ECMAScript5 era, indexOf was also doing something similar to Includes, which is to determine whether an element is present in an array by determining whether the result of indexOf is -1. Later, he created includes for a single purpose. So the main use of indexOf today is to get the first index in the array that matches the parameter.

const arr1 = [1.2.3];
const result = arr1.indexOf(3);
console.log(result); / / 2

const result2 = arr1.indexOf(21);
console.log(result2); // -1
Copy the code

When indexOf matches elements, only elements of the basic type are normally matched. Like reference types, you must use references to match.

const arr1 = [];
const arr2 = [0, [], arr1];
console.log(arr2.indexOf([])); // -1
console.log(arr2.indexOf(arr1)); / / 2
Copy the code

IndexOf and lastIndexOf are a pair. IndexOf should be called firstIndexOf.

lastIndexOf

Direction is a more important pursuit than speed. – bai yansong

Returns the index of the last element in the array, or -1 if it does not exist. Look forward from the back of the array, starting at fromIndex.

Parameters:

SearchElement: The element to be searched.

FromIndex: Optional. Start the reverse search from this location. The default is the length of the array minus 1(arr.length-1), i.e. the entire array is searched. If the value is greater than or equal to the length of the array, the entire array is looked up. If it is negative, consider it an offset forward from the end of the array. Even if the value is negative, the array is still looked up backwards. If the value is negative and its absolute value is greater than the array length, the method returns -1, that is, the array is not looked up.

Return value: the index of the last occurrence of the element in the array. If not found, -1 is returned.

IndexOf and indexOf do almost the same thing, the only difference is that they are matched in the back.

const arr1 = [1.2.3.2];
const result = arr1.lastIndexOf(2);
console.log(result); / / 3

const result2 = arr1.indexOf(2);
console.log(result2); / / 1
Copy the code

flat

Even when we are in the gutter, we must look at the stars. — Film review of The Young You

Flat is a new API added in 2019, but the need to “flatline multidimensional arrays” has been there for a long time, but not to a high degree, so it hasn’t been given much official attention until now.

In the early days of JavaScript, in fact, before the API was opened in 2019, we were still using our own flattening API to implement this functionality, which you can see in the code below.

The function of flat is simple. It is simply to flatten an array. It’s up to you how much you want to flatten it out.

Like an array like this:

let arr = [1.2[3.4[5.6[7.8.9]]]];
Copy the code

Spread out a layer.

let result = arr.flat(1);
console.log(result);// [1, 2, 3, 4, [5, 6, [7, 8, 9]]]
Copy the code

Spread out on two levels.

let result = arr.flat(2);
console.log(result);[1, 2, 3, 4, 5, 6, [7, 8, 9]]
Copy the code

If you don’t know it’s an array of dimensions and want to spread them all out, just pass Infinity.

let result = arr.flat(Infinity);
console.log(result);// [1, 2, 3, 4, 5, 6, 7, 8, 9]
Copy the code

What do you think would happen if you called flat() without passing any arguments? Is it all out?

Well, you’d be wrong.

If you pass no arguments, the effect is the same as passing 1.

flatMap

No amount of intelligence can resist the emptiness of stupidity and commonness.

FlatMap and flat were born together. See if you can guess what ECMAScript does by looking at its magical API naming conventions.

Maybe you’re right. FlatMap is a combination of the flat and Map apis.

If you want each element in an array to copy itself and create a value that’s twice itself to add to the next index.

You need to do two steps, first using the map to get these values, but their return value becomes a two-dimensional array.

The second step, of course, is to amortize the returned array into a one-dimensional array.

let arr = [1.2.3];
const result = arr.map((item) = > [item, item * 2]).flat();
console.log(result);// [1, 2, 2, 4, 3, 6]
Copy the code

What does flatMap do? I’m just going to take this chain call API, and merge it into one API.

let arr = [1.2.3];
const result = arr.flatMap((item) = > [item, item * 2]);
console.log(result);// [1, 2, 2, 4, 3, 6]
Copy the code

Look, what a boring API. I admire the linguistic design genius at ECMA.

This is just a trivial joke, please ignore it.

The famous author Kevin Kelly once said in a speech:

With technology, in the beginning, no one knows what the new invention is best used for. For example, Addison’s phonograph had no idea what it could be used for. The phonograph was gradually used in two scenarios: one was to record the last words of his life; The other is to record speeches in church, including singing. Later, the phonograph was mainly used to record music and so on.

But many of us live with the idea that the world doesn’t need useless innovation.

In my opinion, there is no useless innovation in the world, all innovation has its use. Those who think useless innovations are useless may not be able to wait for the long process of discovering their uses. In fact: existence is reasonable, and reasonable is existence.

Instance iteration method

Iterate over the original array. Operations on the elements of the array are not affected during traversal.

forEach

A thousand desolate, as a dream; Is it prowling there? – yu

Function: Executes the provided function once for each element of an array.

Callback (currentValue [, index [, array]])[, thisArg]);

Parameters:

Callback: A function that is executed for each element in the array and takes three arguments:

  • currentValue: The current element in the array being processed.
  • index: Optional, the index of the current element being processed in the array.
  • arrayOptional,forEach()The array that the method is working on.

ThisArg: This parameter is optional. Used as the value of this when the callback function is executed.

Return value: undefined

Although forEach is one of the most frequently used apis in daily development, there are still a lot of details that are not well known. As a result, many students have unexpected phenomena when using forEach, which makes people confused.

Let’s analyze the details of forEach.

ForEach determines the scope of execution on the first execution. Artificial changes to array elements during forEach execution can affect forEach execution. We learned that there are nine ways to modify an array.

They are add class (push, unshfit, splice), delete class (pop, shift, splice), fill class (copyWithin, fill), change order class (reverse, sort). Arr [I] = x, arr.length = I, and delete array[I] also change arrays in addition to the array’s own methods.

Let’s start with a simple example.

const array = [0.1.2.3.4.5];

array.forEach((currentValue, index, array) = > {
  if (currentValue % 2= = =0) {
    array.push(1);
  }
  console.log(currentValue);
});

console.log(array);
/* 0 1 2 3 4 5 [0, 1, 2, 3, 4, 5, 1, 1, 1, 1] */
Copy the code

As you can see, the new data added to the array is not traversed during forEach.

But if you modify the data during forEach, forEach reads the value at the moment it is traversed. For example, adjust the example above.

const array = [0.1.2.3.4.5];

array.forEach((currentValue, index, array) = > {
  if (currentValue % 2= = =0) {
    array[index + 1] + +; }console.log(currentValue);
});

console.log(array);
/*
0
2
3
3
4
6
[0, 2, 3, 3, 4, 6, NaN]
*/
Copy the code

Matters needing attention

Because there are so many apis, I won’t give you any examples. Here’s a quick summary of forEach’s rules:

1. When the forEach execution starts, the number of executions is determined. No matter how the length of the array changes, it will not be executed more than this number of times. But probably less than that.

2. The length is changed during the forEach execution. When it grows, it doesn’t work. When it diminishes, it reaches the maximum length of the array, and then it ends (skips) the traversal.

3. During the execution of forEach, the element was changed. It reads the value at the moment it traverses the element.

4. ForEach cannot be chained like map or filter, because it returns undefined instead of an array.

5. There is no way to abort or break out of the forEach() loop except by throwing an exception. If you need to abort or break out of a loop, the forEach() method is not the tool to use. The easiest way to do this is to use for, or every, some, and so on.

forEachandfor

Performance issues

In early browsers, forEach’s performance was consistently inferior to that of for. As a result, there is a misconception that even today forEach is not as good as for, but it is not, thanks to the V8 optimization. In newer browsers or nodeJS today, forEach and for performance are pretty much the same, and while for may have a performance advantage, the gap is tiny.

To this end, Teacher Qian also specially did an experiment, in Chrome79 version, the performance comparison of the length of the 1 million array, I ran 5 times:

let array = Array.from({ length: 1000000 }, (v, i) => {
  return i;
});
// for
console.time("log");
for (let i = 0; i < array.length; i++) {}
console.timeEnd("log");
/ / log: 17.89697265625 ms
/ / log: 12.362060546875 ms
/ / log: 18.535888671875 ms
/ / log: 13.59326171875 ms
/ / log: 13.08984375 ms

// forEach
console.time("log");
array.forEach(function(val, i) {});
console.timeEnd("log");
/ / log: 16.1630859375 ms
/ / log: 19.702392578125 ms
/ / log: 18.179931640625 ms
/ / log: 19.887939453125 ms
/ / log: 20.77197265625 ms
Copy the code

You can see that the performance gap is very small, and there are even times when forEach outperforms for.

complexity

For is a classic imperative programming artifact. ForEach, like other iterative methods, is functional programming. The only good thing about “for” is that it’s flexible. Break and continue can jump out at any time. ** But the greatest advantage is also the greatest disadvantage. The power of ** can lead to complex code that is hard to read. Consider the following code.

for (var i = 0, len = grid.length, j = len - 1, p1, p2, sum; i < len; j = i++) {
  p1 = grid[i];
  p2 = grid[j];
  sum += p1 + p2;
}
Copy the code

This is not the case for forEach because it masks the configuration conditions for for.

In the end, He suggests that forEach or another iteration method should be used more than 98% of the time. The other 2% of the time is when you care a little bit about performance and you need to make your own tradeoffs.

entries

Match inside with outside, match words with deeds. – han fei

Returns a new Array Iterator containing key/value pairs for each index in the Array.

Grammar: arr. Entries ()

Return value: an interator object.

The iterator iterator

The word interator appears for the first time. Teacher Qian believes that many students until this concept, but more students may not know. It’s important to be clear here what an Iterator is. To get a better understanding of arrays.

In fact, Iterator can write another article, but qian teacher try to control. Just make the concept clear and concise.

It is the [Symbol. Iterator] attribute on the Iterable object. Specifically, Array is also an iterable.

Before ECMAScript6, objects in JavaScript had no way of distinguishing between objects that could be iterated and objects that could not be iterated. We always say that arrays can be iterated, but we can’t say that some array-like objects can be iterated. Although they can be our iteration by some means, such as Array. The prototype. The forEach. Call (). These are objects, and it’s our custom to decide whether an object can be iterated, and there’s no specification for that. It’s weird. So ECMAScript6 introduced an iterative protocol to address this issue.

All have[Symbol.iterator]Property of an object that belongs to an iterable (可迭代). By calling the iterable on the[Symbol.iterator]Method to obtain an iterator (iterator). By calling the iteratornextMethod can be iterated.

let str = "hello World!";
let iterator = str[Symbol.iterator]();
let _done = false;
while(! _done) {const { value, done } = iterator.next();
  if(! done)console.log(value);
  _done = done;
}
/** "h" "e" "l" "l" "o" " " "W" "o" "r" "l" "d" "!" * * /
Copy the code

Why is the name of this property so strange? It’s not like the length property. ** Realize that all the strange looking designs in JavaScript are there for a reason. ** Because there was no concept of iterators before ECMAScript2015. This is a new concept, and in order to ensure compatibility, you can’t just add the iterator attribute to your object prototype without causing unexpected problems in your JavaScript code. ECMAScript2016 introduces the concept of Symbol. Use Symbol to resolve attribute conflicts.

We can use the Symbol. Iterator property to create iterable objects.

class Rand {[Symbol.iterator]() {
    let count = 0;
    return {
      next: (a)= > ({
        value: count++,
        done: count > 5,})}; }}var rand = new Rand();
var iterator = rand[Symbol.iterator]();
iterator.next(); // {value: 0, done: false}
iterator.next(); // {value: 1, done: false}
// ..
iterator.next(); // {value: 5, done: false}
iterator.next(); // {value: undefined, done: true}
Copy the code

The above code may look fancy, but the syntax is simple. The Symbol. Iterator method returns an object with the next method. The next method returns an object containing the value and done properties each time it is called, and that’s it.

Value indicates the value of the current iteration, and done indicates whether the iteration is over.

Note: An iterable and an iterator are not the same thing. The only connection is that iterables contain a Symbol. Iterator property, which refers to an iterator object.

ECMAScript6 also adds a new syntax called the Spread syntax. Iterables Can use this operator to expand an iterable.

let str = "hello World!";
let iterator = str[Symbol.iterator]();
let _done = false;
console.log(... str);/* "h" "e" "l" "l" "o" " " "W" "o" "r" "l" "d" "!" * /
Copy the code

The new for of syntax in ECMAScript6 also loops around the value and done of the iterator.

If you know anything about data structures, isn’t this just a one-way list? Not to mention, iterator is a unidirectional linked list.

Having understood the concept of iterators, we went back to Entries.

var arr = [1.2.3];
var iterator = arr.entries();
iterator.next();
/*
{value: Array(2), done: false}
value: (2) [0, 1]
done: false
*/
iterator.next();
/*
{value: Array(2), done: false}
value: (2) [1, 2]
done: false
__proto__: Object
*/
Copy the code

Entries converts arrays into iterators. Each value iterated from this iterator is an array of the form “subscript, value”. What’s the use of that? In fact, thousands of teachers will not think of what use, but when you should use it, naturally know what its application scenario is. (If you can remember that there is such an API.)

every

The world of things often into the trapped about, and lost in luxury. – lu you

Function: tests whether all elements in an array pass a specified function test. It returns a Boolean value.

Syntax: arr. Every (callback[, thisArg])

Parameters:

Callback: A function that tests each element and takes three arguments:

  • Element: The current value for the test.

  • Index: Optional, the index of the current value for the test.

  • Array: Optional, call the current array of every.

ThisArg: The value of this used when executing the callback.

Return value: True if each return of the callback is a Truthy value, false otherwise.

Every is very similar to some, in fact every is very similar to the earlier iterations, or more appropriately, the earlier iterations. The difference between every and forEach is twofold. First, the execution of every stops traversal if the condition is not met. Second, every has a return value.

const arr = [0.1.2.30.4.5];
const result = arr.every(function(item, index) {
  console.log(index);
  /* 0 1 2 3 */
  return item < 10;
});
console.log(result); // false
Copy the code

some

Practice makes perfect, shortage in one; Success depends on forethought, destroyed by over. – han yu

Function: Tests whether at least one element in an array passes the provided function test. It returns a value of type Boolean.

Some (callback(element[, index[, array]])[, thisArg])

Parameters:

Callback: A function that tests each element and takes three arguments:

  • element

    The element in the array being processed.

  • The index of the optional

    The index of the element being processed in the array.

  • An array of optional

    Some () is the array to be called.

ThisArg: Optional, this value to use when executing the callback.

Return value: returns true if at least one element of the array passes the callback test; The return value is false if none of the elements pass the callback test.

Some is like every, except that some stops traversing when it hits the first element that fits the criteria. So there’s not much to say here. Take the example of Every here and you can see the difference.

const arr = [0.1.2.30.4.5];
const result = arr.some(function(item, index) {
  console.log(index);
  / / 0
  / / 1
  return item < 10;
});
console.log(result); // true
Copy the code

filter

Birds of a feather flock together. — The Book of Changes

Function: Creates a new array containing all the elements that passed the tests implemented by the provided function.

Var newArray = arr.filter(callback(element[, index[, array]])[, thisArg])

Parameter: callback: a function that tests each element of the array. Returning true means that the element passed the test and is retained; false does not. It takes the following three arguments:

  • element: The element currently being processed in the array.
  • index: Optional, the index of the element being processed in the array.
  • array: Optional, calledfilterOf the array itself.

ThisArg: Optional, the value used for this when executing the callback.

Return value: a new array of elements that passed the test, or an empty array if no array elements passed the test.

We can understand filter in one sentence, take what we want.

const arr = [0.1.2.3.4.5];
const result = arr.filter(function(item, index) {
  return item % 2= = =0;
});
console.log(result); / / [0, 2, 4]
Copy the code

Filter and Map were the first apis to be added in ES6. ForEach can also implement the filter function when there is no filter.

const arr = [0.1.2.3.4.5];
let result = [];
arr.forEach(function(item, index) {
  if (item % 2= = =0) { result.push(item); }});console.log(result); // true
Copy the code

find

Courage leads to heaven, cowardice to hell. – Seneca

Function: Returns the value of the first element in an array that satisfies the provided test function. Otherwise, return undefined.

Syntax: arr.find(callback[, thisArg])

Parameters:

Callback: a function that is executed on each item of the array and takes three arguments:

  • element: The element currently traversed.
  • index: Indicates the index being traversed. This parameter is optional.
  • array: Optional: The array itself.

ThisArg: Optional, the object used for this when performing the callback.

Return value: the value of the first element in the array that satisfies the provided test function, otherwise undefined is returned.

const arr = [0.1.20.30.40];
const result = arr.find((item) = > item > 10);
console.log(result);/ / 20
Copy the code

findIndex

Get, I am lucky; No, my life, that’s all. – xu zhimo

Function: Returns the index of the first element in an array that satisfies the provided test function. Otherwise, return -1.

Syntax: arr.findIndex(callback[, thisArg])

Parameters:

Callback: This function is executed for each element in the array, automatically passing the following three arguments:

  • element: The current element.
  • index: The index of the current element.
  • array: callfindIndexThe array.

ThisArg: Optional. Callback is executed as the value of this object.

Return value: the index of the first element in the array by providing the test function. Otherwise, return -1.

findIndexSo the return is going to befindReturns the index of the element.

const arr = [0.1.20.30.40];
const result = arr.findIndex((item) = > item > 10);
console.log(result);/ / 2
Copy the code

keys

He who knows others is wise, and he who knows himself is wise. He who conquers others is stronger than himself. Lao tzu

Return an Array Iterator containing each index key in the Array.

Grammar: arr. Keys ()

Return: a new Array iterator object.

let arr = ['a'.'b'.'c'];
const result = arr.keys();
for(let key of result){
  console.log(key);  
}
/*
0
1
2
*/
Copy the code

Turns an array into an iterator that stores all of the array’s indexes.

Keys Unlike object. keys, keys do not ignore the empty element.

let arr = ['a'.'b'.'c',,];const result = arr.keys();
for(let key of result){
  console.log(key);  
}
/*
0
1
2
3
4
5
*/
Copy the code

map

If there is, change; if not, encourage. — The Analects of Confucius

What it does: Creates a new array with the result of calling one of the provided functions for each element in the array.

Grammar:

var new_array = arr.map(function callback(currentValue[, index[, array]]) {
 // Return element for new_array 
}[, thisArg])
Copy the code

Parameters:

Callback: A function that generates a new array element, taking three arguments:

  • currentValue:callbackThe current element in the array being processed.
  • index: optional,callbackIndex of the current element being processed in the array.
  • array: optional,mapAn array of method calls.

ThisArg: Optional, the value is used as this when executing the callback function.

Return value: The result of the callback function makes up each element of the new array.

Map is one of the oldest apis in ECMAScript2015, and its main purpose is to map an array. Its functionality can also be implemented using forEach.

Like doubling all the elements of an array.

let arr = [1.2.3.4.5.6.7];
const result = arr.map(function(item) {
    return item * 2;
});
console.log(result);// [2, 4, 6, 8, 10, 12, 14]
Copy the code

ForEach can also be implemented, but is a little more complicated than Map.

let arr = [1.2.3.4.5.6.7];
const result = [];
arr.forEach(function(item) {
    result.push(item * 2);
});
console.log(result);// [2, 4, 6, 8, 10, 12, 14]
Copy the code

Since you can do both, map is cleaner. So when should you use a map?

1. Whether to return a new array.

2. Whether to get the return value from the callback function.

Map can be used if either condition is met, otherwise forEach or for… Of.

The most common use is to extract some value from an array of objects.

let arr = [
  { name: "dog".age: 11 },
  { name: "cat".age: 4 },
  { name: "Xiao Ming".age: 15},];const result = arr.map(function(item) {return item.age});
console.log(result); / / [11, 4, 15]
Copy the code

When you don’t know if you should use a map, don’t bother, because the main point of a map is to simplify some code.

reduce

Man’s life is short, but if despicable to live this life, it is too long. — William Shakespeare

Action: Execute a reducer function (ascending) that you provide for each element in the array and aggregate the results into a single return value.

Callback (callback(accumulator, currentValue[, index[, array]])

Parameters:

Callback: A function that executes each value in the array (except the first value if initialValue is not provided), with four arguments:

  • Accumulator accumulates the return value of the callback. It is the cumulative value, or initialValue, returned when the callback was last called (see below).

  • CurrentValue: The element being processed in the array.

  • Index: Optional, the index of the current element being processed in the array. If initialValue is provided, the starting index number is 0, otherwise it starts at index 1.

  • Array: An optional array to call reduce().

InitialValue: Optional, as the value of the first argument when the callback function is first called. If no initial value is provided, the first element in the array is used. Calling Reduce on an empty array with no initial value will report an error.

Return value: the result of the cumulative processing of the function.

let arr = [1.2.3.4.5.6];
const result = arr.reduce(function(acc, val) {
    return acc + val;
});
console.log(result);/ / 21
Copy the code

Compared to apis like Map and Filter, Reduce seems a little different. What’s the difference?

The literal meaning of reduce is “reduce.” In fact, it’s better to call it a combination.

For example, fitness counts protein, fat, and carbohydrates.

This is a nutrition list for food.

const nutritionFacts = {
  "🥚": {
    carbohydrate: 3.// Carbohydrates
    protein: 13./ / protein
    fat: 9./ / fat
    calories: 144/ / heat
  },
  "🍏": {
    carbohydrate: 12.protein: 0.fat: 0.calories: 52
  },
  "🍌": {
    carbohydrate: 21.protein: 1.fat: 0.calories: 91
  },
  "🍞": {
    carbohydrate: 58.protein: 8.fat: 5.calories: 312
  },
  "🥦": {
    carbohydrate: 3.protein: 4.fat: 1.calories: 33
  },
  "🥩": {
    carbohydrate: 2.protein: 20.fat: 4.calories: 125}};Copy the code

Next, we can encapsulate a function that calculates heat using reduce.

const calculation = (foods) = > {
  return foods.reduce((nutrition, food) = > {
    return {
      carbohydrate:
        nutritionFacts[nutrition].carbohydrate +
        nutritionFacts[food].carbohydrate,
      protein: nutritionFacts[nutrition].protein + nutritionFacts[food].protein,
      fat: nutritionFacts[nutrition].fat + nutritionFacts[food].fat,
      calories:
        nutritionFacts[nutrition].calories + nutritionFacts[food].calories
    };
  });
};

const result = calculation(["🥩"."🥦"]);
console.log(result);
/* { calories: 158, carbohydrate: 5, fat: 5, protein: 24 } */
Copy the code

Try it a little more and you’ll find a BUG in the above code. If you don’t find it, keep trying.

The BUG is that if you only eat a piece of beef, it will return it to you intact. (This is not true, the correct answer should be 💩)

const result = calculation(["🥩"]);
console.log(result);/ / "🥩"
Copy the code

So how do you fix it?

First of all, determine the cause. What causes this phenomenon? You may have noticed that if the length of the reduce caller is 1, it doesn’t call the logic of the callback, but returns the element directly.

So following this line of thinking, the modification method basically returns a value based on the length of the passed parameter foods, and if length is 1, directly returns its corresponding nutrient. You can write the following code:

if (foods.length === 1) {
	const { carbohydrate, protein, fat, calories } = nutritionFacts[foods[0]].return {
      carbohydrate,
      protein,
      fat,
      calories
    };
} else if (foods.length < 1) {
    // The original logic
}
Copy the code

But this is obviously clumsy. Is there a smarter way to do it? Of course there is, but there is a second argument to reduce. If the second argument is not passed, the first argument is taken as the initial state. In this case, the first value is skipped. But once you have the second parameter, the first value is not skipped. So we can solve this more elegantly with the second parameter.

nutritionFacts["💧"] = {carbohydrate: 0.protein: 0.fat: 0.calories: 0};// Add 💧 to default all nutrients to 0

const calculation = (foods) = > {
  return foods.reduce((nutrition, food) = > {
    return {
      carbohydrate:
        nutritionFacts[nutrition].carbohydrate +
        nutritionFacts[food].carbohydrate,
      protein: nutritionFacts[nutrition].protein + nutritionFacts[food].protein,
      fat: nutritionFacts[nutrition].fat + nutritionFacts[food].fat,
      calories:
        nutritionFacts[nutrition].calories + nutritionFacts[food].calories
    };
  }, "💧");
};
Copy the code

The clever student found an equation.

["🥩"."🥦"].reduce(reducer, initialState);

[initialState, "🥩"."🥦"].reduce(reducer);
Copy the code

In both cases, the effect is equal.

If you’ve used Redux or Rxjs, you should see something familiar from the above code. Reducer and initialState.

Yes, they all use the same ideas and principles.

You can think of it this way: Reduce in Redux is not synchronous and automatic, but asynchronous and manually activated. CurrentState, the first parameter of reducer, is the basic state. Each time a different action is launched, a reduce call is triggered. CurrentValue corresponds to the type and payload passed by the Action in Redux.

You might not get it a little bit, but that’s okay. You’ll get it.

For can also implement reduce. Like counting carbs.

let foods = ["🥩"."🥦"];
let result = {};
for(let i = 0; i < foods.length; i++) {
    result.carbohydrate = (result.carbohydrate || 0) + nutritionFacts[foods[i]].carbohydrate;
}
console.log(result);// { carbohydrate: 5 }
Copy the code

As you can see from the above example, for has one more variable than Reduce to store the result value of the last calculation.

There is a value for reduce, but thanks to functional programming, it is not visible to you directly. You may not feel that reduce has much of an advantage over for right now. But when you’re faced with a file of hundreds of lines of code, it’s easy to see the advantage of Reduce automatically maintaining this variable for you.

Another point to note is that reduce is literally a decrease, but it is not actually a decrease. The first argument in the callback function can be any value, such as an array or an object. If it’s an array or an object, it’s an infinitely extensible data structure. So don’t be fooled by the literal meaning of reduce.

let arr = [0.1.2.3.4.5];
const result = arr.reduce((accumulator, currentValue) = > {
  accumulator.push(currentValue * 2);
  returnaccumulator; } []);console.log(result);// [0, 2, 4, 6, 8, 10]
Copy the code

See, Reduce can do something similar to Map. Similarly, reduce can also implement functions such as forEach and Filter.

reduceRight

Don’t shy away from distress and difficulty, stand up to it and challenge it, and then overcome it. — Ikeda Daisaku

Action: Accepts a function as an accumulator and reduces each value of an array (from right to left) to a single value.

ReduceRight (callback(currentValue[, index[, array]])[, initialValue])

Parameters:

Callback: a callback function that operates on each element in an array and takes four arguments:

  • accumulator: the return value of the last callback call, or suppliedThe initialValue.
  • currentValue: The element currently being processed.
  • index: Optional, the index of the element currently being processed in the array.
  • array: Optional, callreduceRight()The array.

InitialValue: Optional, the value is used as the accumulator for the first call to the callback. If no initial value is provided, the last element in the array is used and skipped. Calling Reduce or reduceRight on an empty array with no initial value creates a TypeError.

Return value: The value returned after execution.

ReduceRight and Reduce are twins. The difference is that they iterate from the back to the front. This is analogous to indexOf and lastIndexOf.

values

I won’t argue with anyone. I won’t argue with anyone. – rand

Return a new Array Iterator containing the value of each index of the Array.

Grammar: arr. Values ()

Return value: a new Array iteration object.

let arr = ['a'.'b'.'c'];
const iterator = arr.values();

for(let item of iterator){
  console.log(item);
}
/*
"a"
"b"
"c"
*/
Copy the code

Symbol.iterator

All maverick personality means strong — Camus

The @@iterator property and array.prototype.values () property are the same function object.

Grammar: arr/Symbol. The iterator ()

Return value: same as values.

This method is generally not recommended, just use values.

let arr = ['a'.'b'.'c'];
const iterator = arr[Symbol.iterator]();

for(let item of iterator){
  console.log(item);
}
/*
"a"
"b"
"c"
*/
Copy the code

Object’s array-related methods

entries

To forget the past is to betray. Lenin

Returns an array of key and value pairs for the enumerable properties of a given object, arranged with the for… The in loop returns the same order as it traverses the object (the difference is that the for-in loop also enumerates the properties in the prototype chain).

Grammar: Object. Entries (obj)

Parameter: obj: An object that can return a key-value pair for its enumerable properties.

Return value: an array of key-value pairs for a given object’s own enumerable property.

let animals = {"dog": "🐶"."cat": "🐱"."bird": "🐦"."wolf": "🐺"};
const result = Object.entries(animals);
console.log(result);/ / [[" dog ", "🐶"], [" cat ", "🐱"], [" bird ", "🐦"], [" Wolf ", "🐺"]]
Copy the code

When an object is converted to an array, the order in which the elements are arranged does not depend on the order in which the object is defined. In is consistent.

There are two common application scenarios for entries.

1. Iterate over objects

for(let [key, value] of Object.entries(animals)) {
    console.log(`${key}:${value}`);
}
/* "dog:🐶" "cat:🐱" "bird:🐦" "Wolf :🐺" */
Copy the code

Or use forEach, and the result is the same.

Object.entries(animals).forEach(([key, value]) = > console.log(`${key}: ${value}`));
/*
"dog: 🐶"
"cat: 🐱"
"bird: 🐦"
"wolf: 🐺"
*/
Copy the code

2. Convert it to a Map

const map = new Map(Object.entries(animals));
console.log(map.size); / / 4
console.log(map.has('dog')); // true
console.log(map.get('cat')); / / "🐱"
Copy the code

keys

From good to ascend, from evil to collapse. One Mandarin

Returns an array of self-enumerable properties of a given object. The in loop returns the same order as it traverses the object.

Grammar: Object. Keys (obj)

Parameter: obj: The object to return for enumerating its own properties.

Return value: an array of strings representing all the enumerable properties of a given object.

Keys collects all the enumerable property names of an object into an array.

let animals = {"dog": "🐶"."cat": "🐱"."bird": "🐦"."wolf": "🐺"};
const result = Object.keys(animals);
console.log(result);// ["dog", "cat", "bird", "wolf"]
Copy the code

values

Gong chongwei zhi, industry wide but diligence. The Book of History

Returns an array of all enumerable property values of a given object.

Grammar: Object. Values (obj)

Parameter: obj: The object to which the value of an enumerable property is returned.

Return value: an array containing the values of all the enumerable properties of the object itself.

Values works in much the same way as Entries. Both automatically ignore prototype chains and non-enumerable properties.

let animals = {"dog": "🐶"."cat": "🐱"."bird": "🐦"."wolf": "🐺"};
const result = Object.values(animals);
console.log(result);// ["🐶", "🐱", "🐦", "🐺"]
Copy the code

Values can easily convert an object to a Set.

Let animals = {" dog ":" 🐶 ", "cat" : "🐱", "bird" : "🐦", "Wolf" : "🐺"}; const set = new Set(Object.values(animals)); console.log(set); // Set(4) {"🐶", "🐱", "🐦", "🐺"}Copy the code

Values and Keys are a pair of similar apis.

fromEntries

If you do not forget a lot, life can not continue. — Balzac

Function: Converts a list of key-value pairs to an object.

Grammar: Object. FromEntries (iterable);

Parameter: iterable: An iterable object, such as Array, Map, or other objects that implement an iterable protocol.

Return value: a new object with the corresponding properties provided by the iterated object entry.

FromEntries is a new API added in 2019. FromEntries is an inversion function for entries, which was also designed to solve the problem of data being retained in arrays after entries were used.

let animals = {"dog": "🐶"."cat": "🐱"."bird": "🐦"."wolf": "🐺"};
const animalsList = Object.entries(animals);
const animals2 = Object.fromEntries(animalsList);
console.log(animals2);
/ * {bird: "🐦", the cat: "🐱," dog: "🐶," Wolf: "🐺} * /
Copy the code

FromEntries is not limited to converting an Array to an Object. It converts any iterable, such as a Set and a Map, to an Object.

String to array

split

When there is nothing to do or tired, the sage sees its self-study. – zuo zongtang

Uses the specified separator String to split a String into an array of substrings, with a specified separator String to determine the location of each split.

Separator [, limit]]

Parameters:

Separator: Specifies the string that represents the point at which each split should occur. Separator can be either a string or a regular expression. If the plain text delimiter contains more than one character, the entire string must be found to represent the split point. If the separator is omitted or does not occur in STR, the returned array contains one element consisting of the entire string. If the delimiter is an empty string, STR is returned as an array of each character in the original string.

Limit: An integer that limits the number of split fragments to be returned. When this parameter is provided, the split method splits the string at each occurrence of the specified delimiter, but stops when the restriction item has been placed in the array. If the end of the string is reached before the specified limit is reached, it may still contain fewer entries than the limit. The rest of the text is not returned in the new array.

Return value: Returns an Array of the source string separated by the position where the separator appears.

const str = "hello,world!";
const result = str.split(', ');
console.log(result);// ["hello", "world!"]
Copy the code

An array returned by splitting strings with each element being a substring of the source string.

If you want to restore the split array, you can use join.

const str2 = result.join(', ');
console.log(str2);// "hello,world!"
Copy the code

Bottom line: What should we do with such a large and complex API?

Back in ECMAScript5.0, there weren’t that many apis. You can check out Advanced Programming in JavaScript (Version 3), and there are just a few key apis.

From now on, very few people can fully understand which APIS to use in which situations without resorting to documentation. Remember, all of these apis are just a data type called Array. And are you sure you’ve remembered and understood all of this? I’m sure you don’t remember much. You’re probably wondering how to remember them right now.

Teacher Qian’s advice is: don’t memorize them deliberately, it’s meaningless.

If you’re a long-time JavaScript worker; Or a seasoned JavaScript enthusiast who can use these features in refactoring historical projects and developing new ones as appropriate. Be aware of Transplier support though. Practice is a great way to deepen your memory. ** After you’ve practiced enough, you can talk to other people and share what you’ve learned. Don’t just stay in your knowledge frame, get out and about.

If you don’t use JavaScript very often, or if JavaScript isn’t your only language, for example, you’re a full-stack engineer who also knows other languages, such as Java. Then you don’t need to remember the entire API. Because there are more and more important things to remember in Java.

However, there are a few key, core apis that you must keep in mind anyway.

What are the key and core ones? Those apis from the ECMAScript5.0 era and the first ones to be added in ECMAScript2015. With that in mind, you can solve all scenarios. As for ecmascript’s post-2015 apis, they are mostly designed to fix historical issues or to implement single-duty designs. Interesting, but not necessarily useful.

Amazing Weapon: Array is a tool for beginners and lazy people

Because the Array API is too many, there is no serious learning and understanding, plus a lot of practice and experience. It’s hard to remember all the apis. In this case, teacher Qian will write this article. But this article is a little too much. Teacher also studied how to lazy way. For example, right now you don’t remember and understand all the apis, but you need to use them, and you need to use them right. What to do? It’s very slow to check the documents every time.

No matter, a beautiful programmer named Sarah Drasner has opened source to an Array explorer. All you have to do is select the Array operation you want, and you get the API.

In fact, Teacher Qian thinks that if ** is a general engineer, there is no need to master Array. Of course, if you want to be more than an engineer, then Teacher Qian still recommends that you master Array. ** So don’t fluke, it is a blessing not a disaster, but a disaster to hide. Teachers believe that every reading this article you, are not just a general engineer.

Icing on the cake: Community extensions to Array

How do I extend archetypes?

Thanks to ECMAScript’s flexible prototyping system, each data type can add new functionality through prototyping extensions.

This is very different from Java. Java extends arrays through inheritance.

class MyArrayList extends ArrayList{
    public void hello(a){
        System.out.println("hello"); }}Copy the code

And when you use arrays after that, you can no longer use ArrayList, but instead use MyArrayList.

MyArrayList arr = new MyArrayList();
arr.add(1);
arr.add("2");
arr.hello();// hello
Copy the code

There is another option, which is to modify the JDK directly.

ECMAScript is much simpler. Extension does not affect the original use mode.

Array.prototype.hello = function() {
    console.log("hello");
}

[].hello();// hello
Copy the code

Of course, ECMASCript also supports inheritance for extensions.

class MyArray extends Array {
  hello() {
    console.log("hello"); }}Copy the code

The bad thing is, you can create arrays with the new keyword, you can’t create arrays with literals. According to our custom, 99% of people like to use literal.

var arr = new MyArray();
arr.hello(); // hello

var arr2 = [];
arr2.hello(); // Uncaught TypeError: [].hello is not a function
Copy the code

Prototype. js is the grandfather of prototype extensions. It was followed by right.js, Ext.js, undersore-js and others. For a long time, almost every library extended arrays. It’s as if you can’t call yourself a JavaScript library without extending Array. The Array already has over 30 properties and methods. When you extend the Array, do you think about the Array? Of course, none of them thought about it, but ECMA did. So now the native Array is very, very powerful, and these libraries are not.

At the moment, with the exception of lodash.js, there are almost no other libraries of this type. But the methods they extend are really necessary, because they are solutions that people encounter when writing business, so they are still worth learning. If you don’t think it makes sense to learn this right now, you’re not writing enough code. Write more complex business, and you’ll come across usage scenarios sooner or later.

Extension API implementation

Teacher Qian recommended a more mature array extension library, D3-array. This library is perfect and can be used directly in the project.

Some of the more common extensions are shown below.

remove

Action: Removes elements according to their subscripts.

Implementation:

Array.prototype.remove = function(index) {
  return!!!!!this.splice(index, 0);
};
Copy the code

Usage:

var arr = ["a"."b"."c"];
const result = arr.remove(1);
console.log(result); // true
console.log(arr); // ['a', 'c']
Copy the code

removeAt

Action: Removes elements from the element

Implementation:

Array.prototype.removeAt = function(item) {
  const index = this.indexOf(item);
  if(index ! = =- 1) {
    return!!!!!this.splice(index, 1);
  }
  return false;
};
Copy the code

Usage:

var arr = ["a"."b"."c"];
const result = arr.removeAt(1);
console.log(result); // true
console.log(arr); // ['b', 'c']
Copy the code

shuffle

Function: Shuffle the array, shuffle the array elements.

Shuffle algorithm is a relatively complex API. It’s a very old problem, going back to the Knuth Shuffle algorithm in 1938, before we were born.

The procedure for a Knuth shuffle is as follows:

1. Record the number from 1 to length-1.

2. Select a random number k from 1 to the remaining untraversed numbers.

3. Start counting from the end, each time remove the random k and place it at the end of the array.

4. Repeat steps 2-3 until all numbers have been traversed.

At its core is the use of the Random function provided by the Math object.

There are N well implemented libraries on NPM, knuth-shuffle-seeded and knuth-shuffle.

Implementation:

Array.prototype.shuffle = function() {
  for (len = this.length - 1; i > 0; i--) {
    rand = Math.floor(Math.random() * i);
    temp = this[rand];
    this[rand] = this[i];
    this[i] = temp; }};Copy the code

Usage:

let arr = [0.1.2.3.4.5.6];
arr.shuffle();
console.log(arr); // [5, 4, 6, 1, 0, 2, 3]
Copy the code

random

Function: Extracts a random element from an array.

Implementation:

Array.prototype.random = function() {
  return this[Math.floor(Math.random() * this.length)];
};
Copy the code

Usage:

let arr = [0.1.2.3.4.5.6];
const result = arr.random();
console.log(result);
Copy the code

flatten

Function: Flattens an array and returns a one-dimensional array.

Implementation:

Array.prototype.flatten = function() {
  let result = [];
  this.forEach(function(item) {
    if (Array.isArray(item)) {
      result = result.concat(item.flatten());
    } else{ result.push(item); }});return result;
};
Copy the code

Usage:

let arr = [0[1.2].3[[[4].5].6]].const result = arr.flatten();
console.log(result); // [0, 1, 2, 3, 4, 5, 6]
Copy the code

After ECMAScript2019, the native Array has the flatAPI, so this third party API is no longer needed. But it can still be used in higher environments.

unique

Function: Deduplicates an array, returning an array with no duplicate elements.

Before ECMAScript6, the implementation of Unique was relatively cumbersome, but after ECMAScript6, with the new data structure Set, the implementation of Unique was very simple.

Use Set to implement:

Array.prototype.unique = function() {
  let set = new Set(this);
  return [...set];
};
Copy the code

ECMAScript5 implementation:

Array.prototype.unique = function() {
  var result = [];
  loop: for (let i = 0; i < this.length; i++) {
    for (let j = i + 1; j < this.length; j++) {
      if (this[i] === this[j]) {
        continue loop;
      }
    }
    result.push(this[i]);
  }
  return result;
};
Copy the code

Usage:

let arr = [0.1.1.1.2.3.3];
const result = arr.unique();
console.log(result); // [0, 1, 2, 3]
Copy the code

compact

Remove null and undefined from an array and return a new array.

Implementation:

Array.prototype.compact = function() {
  return this.filter(function(item) {
    returnitem ! =null;
  });
};
Copy the code

Usage:

let arr = [0.null.1.undefined.2];
const result = arr.compact();
console.log(result); / / [0, 1, 2]
Copy the code

pluck

Get a property of each object in an array and return it as an array.

Implementation:

Array.prototype.pluck = function(propertyName) {
  let result = [];
  this.forEach(function(item) {
    if (propertyName initem) { result.push(item[propertyName]); }});return result;
};
Copy the code

Usage:

let arr = [
  { name: "dog".age: 11 },
  { name: "cat".age: 4 },
  { name: "Xiao Ming".age: 15},];const result = arr.pluck("age");
console.log(result); / / [11, 4, 15]
Copy the code

groupBy

Function: Returns objects grouped according to specified conditions.

Implementation:

Array.prototype.groupBy = function(key) {
  return this.reduce((acc, i) = > {
    (acc[i[key]] = acc[i[key]] || []).push(i);
    return acc;
  }, {});
}
Copy the code

Use:

let arr = [
  {
    name: "Jin yong".profession: "Writer"
  },
  {
    name: "Bruce Lee".profession: "Martial Artist"
  },
  {
    name: "Cologne".profession: "Writer"}];const result = arr.groupBy("profession");
console.log(result);
/* {name: [{name: Jin Yong, profession: writer}, {name: Dragon, profession: writer}], martial artist: [{name: Bruce Lee, profession: "Martial artist"}]} */
Copy the code

The inspiration for this API comes from the GROUP BY operation in SQL.

union

Use: take the union of two arrays.

The implementation idea is very similar to unique, two arrays are joined together, and then re-go.

Implementation:

Array.prototype.union = function(arr) {
  let set = new Set(this.concat(arr));
  return [...set];
};
Copy the code

Usage:

const result = [1.2.3.4.5].union([2.3.4.5.6]);
console.log(result);// [1, 2, 3, 4, 5, 6]
Copy the code

intersect

Use: the intersection of two arrays.

Implementation:

Array.prototype.intersect = function(arr) {
  return this.filter(function(item) {
      return ~arr.indexOf(item);
  });
};
Copy the code

Usage:

const result = [1.2.3.4.5].intersect([2.3.4.5.6]);
console.log(result);// [2, 3, 4, 5]
Copy the code

diff

Use: take the difference set between two arrays.

Array.prototype.diff = function(arr) {
    let result = [];
    for(let i = 0; i <this.length; i++) {
        if(! arr.includes(this[i])) {  
            result.push(this[i]); }}return result;
}
Copy the code

Usage:

let arr = ['🐇'.'🐘'.'🐿 ️'.'🐑'];
let arr2 = ['🐇'.'🐑'.'🐒'.'🐄'];
const result = arr.diff(arr2);
console.log(result);/ / [🐘 ", "" 🐿 ️"]
Copy the code

min

Use: take the minimum value in an array, only for numeric arrays.

The idea is to use a combination of math.min and apply functions.

Array.prototype.min = function() {
    return Math.min.apply(0.this);
}
Copy the code

Usage:

const result = [1.2.3.4.5].min();
console.log(result);/ / 1
Copy the code

max

Use: take the maximum value in an array, only for numeric arrays.

The implementation of Max is similar to that of MIN.

Array.prototype.max = function() {
    return Math.max.apply(0.this);
}
Copy the code

Usage:

const result = [1.2.3.4.5].max();
console.log(result);/ / 5
Copy the code

chunk

Use: divide a large array into N smaller arrays.

Array.prototype.chunk = function(size) {
    let chunked = [];
    let arr = this.slice();
    while(arr.length) {
        chunked.push(arr.splice(0, size));
    }
    return chunked;
}
Copy the code

Usage:

const arr =  [1.2.3.4.5.6.7];
const result1 = arr.chunk(2);
console.log(result1);// [[1, 2], [3, 4], [5, 6], [7]
const result2 = arr.chunk(3);
console.log(result2);// [[1, 2, 3], [4, 5, 6], [7]
const result3 = arr.chunk(4);
console.log(result3);// [[1, 2, 3, 4], [5, 6, 7]]
Copy the code

conclusion

How to not contaminate the prototype chain?

All of the examples above are implemented by extending the prototype chain. If you don’t want to change the prototype chain, you can implement these functions in other ways, such as writing them all as functions or as a class.

The example of writing a class was given at the beginning of this section. I’m just going to talk about how to rewrite it as a function, but it’s very simple. Take remove for example.

How to implement the prototype chain:

Array.prototype.remove = function(index) {
  return!!!!!this.splice(index, 0);
};
Copy the code

As a function:

function remove(arr, index) {
  return!!!!! arr.splice(index,0);
};
Copy the code

Usage:

remove([1.2.3.4].1);
Copy the code

Simply add an array argument to the beginning of the function’s argument list, and change the “this” inside the function to the argument passed in. It’s really simple, but it doesn’t change the way the array is used.

The pursuit of elegant simplicity

There are a lot of neat people out there. They are meticulous in their pursuit of code and prefer more elegant implementations. Lambda expressions, on the other hand, are a way to simplify your code to the extreme.

For example, using lambda to simplify the chunk implementation.

Array.prototype.remove = index= >!!!!! arr.splice(index,0);
Copy the code

It’s much easier. But it’s not obvious because the original implementation was short. So let’s look at another example.

Use math.ceil to modify the chunk.

const chunk = (arr, n) = > [...new Array(Math.ceil(arr.length / n))].map((x, i) = > arr.slice(i * n, (i + 1) * n ));
Copy the code

Can you see some comparison now? N lines of code are converted to 1 line.

There are always two sides to this. It looks much simpler, but it costs more to read this line of code than it would have otherwise.

Programming is an art, since it is an art, there is no absolute advantages and disadvantages. Because everyone has a different understanding of the work.

The idea of extending the API

In fact, if you look carefully enough, you’ll find that all extension apis depend on the original API or some other API in some way. Combine operations that originally required two or more steps into an easy-to-use API. If you have played League of Legends, you should know that there is a hero named Ruiwen who has a combo called Lightspeed QA. This combo can do explosive damage in a very short time, but it is very cumbersome to operate, requiring “right click on the enemy for general attack – Q key release skill – right click on the floor to cancel Q skill hard straight”, and then repeat this operation 3 times. Older people, hand speed can not keep up, it is difficult to zero error to play this combo. But the middle-aged are often more intelligent, they use the function of the mouse macro, the operation of the concatenation in advance, the input mouse, when the need to use, only need to press the macro button, you can easily achieve this set of tedious operations. This is very similar to extending aN API. Along these lines, you can imagine and make more practical apis.

Optional reading: Processing at the V8 engine level

In Soul 4, we learned that arrays have a fixed memory range, but JavaScript doesn’t care.

At the language level, if JavaScript is ignored, what does it do at the engine level?

Inside V8, the elements of an array are called elements. To optimize performance, V8 gives arrays a special treatment. It also makes a more precise distinction between types. For example, for elements of type number, at the language level, JavaScript only has a typeof operator to know whether a variable is a number, not whether it is an integer, float, or double. In V8, if all elements in an array are integers, the array’s type is marked as PACKED_SMI_ELEMENTS. If only integer and floating point element types exist, then the array is of type PACKED_DOUBLE_ELEMENTS. In addition, an array contains other elements, all marked as PACKED_ELEMENTS. These array types are not static, but change at run time. But the type of an array can only be changed from a specific type to a normal type. That is, an array that starts with PACKED_SMI_ELEMENTS can only be transitioned to PACKED_DOUBLE_ELEMENTS or PACKED_ELEMENTS. PACKED_DOUBLE_ELEMENTS can only be transitioned to PACKED_ELEMENTS. As long as the initial is an array of type PACKED_ELEMENTS, there is no transition.

All three of these types are compact arrays. The corresponding sparse array, marked HOLEY_ELEMENTS, also has three types. Any kind of PACKED can be transitioned to HOLEY.

Why these two distinctions? Because dense arrays are more efficient in operation than sparse arrays.

What is a dense array? It’s just a stack of contiguous chunks of memory.

What is a sparse array? It’s just a linked list of hashes of memory blocks.

So at the language level, what is a sparse array? It’s an array of empty elements.

let array = [0.1.2]; // PACKED_SMI_ELEMENTS
array.push(2.1); // PACKED_DOUBLE_ELEMENTS
array.push("3"); // PACKED_ELEMENTS
array[10] = "10"; // HOLEY_ELEMENTS
Copy the code

The lower the array type, the worse the performance. And the type transitions of arrays are only going to be from top to bottom, not bottom to top. An array marked as HOLEY_ELEMENTS is no longer marked as PACKED_ELEMENTS, even if empty is filled in.

Small performance tuning tips

This small amount of optimization doesn’t really mean a lot, but it just gives you the best performance.

Avoid reading beyond the length of the array

let array = [0.1.2];
array[10];
Copy the code

The effect of reading data beyond the length of the array is to perform an expensive prototype chain lookup.

In some places in jQuery, there is looping code for this pattern.

for (let i = 0, item; (item = items[i]) ! =null; i++) {
  doSomething(item);
}
Copy the code

This code reads all the elements in the array, and then reads one more. Until you encounter undefined or null elements.

There are three alternatives, traditional for, for-of for iterables, and forEach. Current V8, for-of, and forEach performance is comparable to for.

A worse case is when the value is found in the prototype chain of the array.

let arr = [1.2.3];
arr.__proto__ = { "10": "gg" };
console.log(arr[10]); // "gg"
Copy the code

Avoid element type conversions

let array = [+0.1.2]; // PACKED_SMI_ELEMENTS
array.push(0); // PACKED_DOUBLE_ELEMENTS
Copy the code

Avoid -0, NaN, Infinity, as any of these elements will cause the array to be of type PACKED_DOUBLE_ELEMENTS.

Take precedence over an array rather than an array-like object

Although many objects and arrays are very similar in JavaScript, we can create our own array-like objects from objects. We’ve done all of this up here and demonstrated it. But there is a difference.

For example, a code like this:

let arrayLike = {};
arrayLike[0] = "a";
arrayLike[1] = "b";
arrayLike[2] = "c";
arrayLike.length = 3;
Array.prototype.forEach.call(arrayLike, (value, index) => {
  console.log(`${index}: ${value}`);
});
Copy the code

While running logic is fine, it’s much slower than calling forEach directly from an array, because forEach is highly optimized in V8.

The way to improve performance is to convert an array-like object into an array and then call an array method. Although there is a one-time conversion cost, the performance optimization is worth it, especially if you perform a large number of operations on arrays.

const actualArray = Array.prototype.slice.call(arrayLike, 0);
actualArray.forEach((value, index) = > {
  console.log(`${index}: ${value}`);
});
Copy the code

Another common case is arguments. In the old days, when we wanted to output parameters, we usually did this.

const logArgs = function() {
  Array.prototype.forEach.call(arguments, (value, index) => {
    console.log(`${index}: ${value}`);
  });
};
logArgs("a"."b"."c");
Copy the code

But in ES2015, we can solve this problem with rest parameters.

const logArgs = (. args) = > {
  args.forEach((value, index) = > {
    console.log(`${index}: ${value}`);
  });
};
logArgs("a"."b"."c");
Copy the code

Today we use the Arguments object directly for no reason at all. Unless your code is running on ES5.

To avoid creatingHOLEY

In real-world coding, the difference in performance between accessing dense and sparse arrays is very small and may be too small to be detected or even measured. However, it is still important to maintain extreme coding habits.

let array = new Array(3);
array[0] = 1;
array[1] = 2;
array[2] = 3;
Copy the code

This constructor creates an array of type HOLEY_SMI_ELEMENTS. As described in V8 above, array type transitions only face down, not up. So once it’s marked as HOLEY, it’s always HOLEY. Even if you fill them all up, it won’t help.

A better approach is to use literals to create arrays.

let array = [1.2.3];
Copy the code

This might help optimize the code for some operations on the array.

Author’s note: This part about V8 is not originally created by Teacher Qian. It’s a translation. The original is fromV8 official BlogAs seen above, the author isMathias Bynens. Thousands of teachers read feel good, added some personal understanding, draw lessons from my blog. Those of you who are interested can go and have a lookThe original.

Conclusion: Look at essence from the abstract: kung fu and data

The content of this article is a brief introduction to Array in JavaScript.

Array isn’t that hard. It’s just a way to organize data.

The types of data are the same in all programming languages. Numbers, characters, and Boolean values. In the human mind, there are only three. All other types are based on variations of these three. Of course, some other types are not included in this column, such as bits, buffering. These are not exactly data types. Because they don’t correspond to anything in the real world, they’re computer data types. Other ways of organizing data, such as groups and objects, organize and encapsulate all three types of data. So instead of being a basic data type, they should be called data structures.

It’s very much like boxing or Wing Chun. In the world of boxing, people only have two hands, and the difference in punching is nothing more than direction and Angle. Each school will give them different names, but in the final analysis can only be divided into three types of boxing, one is the straight fist, one is the hook fist, one is the swing fist. And wing Chun also has three batting axes – spread bang fu. This all fits in with the big three data types. The movement of the body and the different sequences of punches, with different speeds and forces, make up what are called “combo punches,” or “moves,” which act as arrays or objects. Quite a way to give birth to one, life two, two three, three things taste.

Martial arts will grow. Jeet Kune Do, founded by Bruce Lee, the king of Kung Fu, the pioneer of MMA and the greatest Chinese of the 20th century, is also derived from traditional Chinese martial arts, wing Chun, mixed with philosophy, Western boxing, karate, jujitsu and many other techniques.

Data can also be derived. Numbers can be derived from int, float, double, long, bigint. Or in base terms, something like INT8, INT16, INT32, int64.

Every language has its own ideas. Golang likes simplicity, JavaScript likes complexity, C likes unlimited, Java and C++ like object-oriented ideas. Just like Tai Chi, Muay Thai, sumo, wrestling, boxing, all have their own rules and ideas. They all have a set of things that they think are right, and they form a system. For example, some traditional Chinese martial arts believe that “three points to lose. On the other hand, taekwondo and Muay Thai have completely opposite views. In view of their own shortcomings, disadvantages, advantages, to make some of their own things, this is the derivative product.

Each faction of programmers has its own set of languages, and Java people care about floats, doubles, ints, and longs. Golang people care about uints, ints, floats, bits. JavaScript programmers only care about numbers. But almost every programmer knows something called JSON.

Let’s ask ourselves a question: why is JSON so common in the industry?

There are two reasons.

One is that it’s simple enough and meets all the needs. JSON has only six data types: number, string, Boolean, object, array, and NULL, but it works for all languages. Whether written to a configuration file or as a data interaction format.

And two, because its full name is JavaScript Object Notation. In the early Days of Ajax, much of the data interaction was in XML. But XML is too tedious to write and does not parse well. JSON came along and directly beat XML to the standard. So far in Web2.0, almost 90% of all web sites are using JSON. When the mobile era came, instead of inventing a better type of data interaction, JSON was adopted directly. Why is that? One is for historical reasons, and the other is unnecessary. Technology moves fast because old technology has pain points. JSON does not, of course, or the pain point is not obvious, and everyone accepts it by default. Even Graphql, a hot new API interaction language, still uses JSON as the underlying data format.

So, I hope you don’t get caught up in the type system of a particular language. It is true that every language has more or less different ideas and features. It’s all about style, not mistakes. Everyone has their own favorite style. It has to do with personality, age, mentality and experience. Some people who like Taijiquan think that taijiquan is just a frappe, and they do not have the actual combat ability. Some people who like Taijiquan think that it is too rude and harmful to the body. It is difficult to distinguish right from wrong, different perspectives, different ideas, different original intentions. In the programmer world, there are some Java programmers who think JavaScript is too messy because it’s too flexible, and there are some JavaScript people who think Java is too annoying because it’s too templatable. All this is inevitable. There are also people who like Java as well as JavaScript, hence TypeScript.

Finally, a word of caution: you can get as much as you practice.

The original address: www.luzhenqian.top/reunderstan…