⚠ important

Most of the features described in this article have been suspended (or even not recommended). They are still common in many books and therefore worth studying.

The comma operator

Is the operator used to separate expressions and return the last expression in the chain.

let oo = (1.2.3)
console.log(oo) / / 3
Copy the code

There are three main expressions 1, 2, and 3. All of these expressions are evaluated, and the last one is assigned to OO.

We see this in the for loop:

for(let i = 0, ii = 1; i< 10; i++, ii--) { ... }
Copy the code

This comes in handy when we want to write short lambda functions:

const lb = (a, b, arr) = > (arr.push(a*b), a*b)
Copy the code

There are two statements, the first pushes the multiplication results into the array ARR, and the second pushes the multipliers A and B into the array. The second result is what is returned to the caller.

It is also useful for ternary operators because, like the short lambda syntax, it accepts only expressions rather than statements.

Second, in

In is the keyword used to check whether an attribute exists in an object. We are in the for… The in loop uses it without realizing that in is also a keyword 🙂

In returns true if there are properties on the object, false otherwise.

const o = {
    prop: 1
}
console.log("prop" in o) // true
Copy the code

See, in can be used independently instead of in for.. In the.

It checks to see if “prop” can be used as a property in an O object. It returns true because we defined the “prop” property in o.

If we check for undefined properties:

const o = {
    prop: 1
}
console.log("prop1" in o) // false
Copy the code

It returns false because “prop1” is not defined in o.

Array constructor

Did you know that we can define arrays without using traditional methods?

const arr = [1.2.3]
Copy the code

How’s that?

We can also use Array:

const arr = new Array(1.2.3)
Copy the code

The permutation of the arguments passed to the Array constructor will form the basis of its index.

1 is the first argument with an index of 0; 2 is the second parameter with an index of 1; 3 is the third parameter with an index of 2.

arr[0] / / 1
arr[1] / / 2
arr[2] / / 3
Copy the code

So,

const arr = new Array(1.2.3)
Copy the code

and

const arr = [1.2.3]
Copy the code

It means the same thing.

There is a problem with using new Array(), for example:

var a = new Array(10.20);
a[0] / / return 10
a.length / / return 2
Copy the code

But:

var a = new Array(10);
a[0] / / returns undefined
a.length / / return 10
Copy the code

This happens when you only give the Array constructor an integer (an integer greater than or equal to 0, otherwise an error will be reported). Why is this nan?

In fact, the new Array constructor is taking the idea from some programming languages where you need to specify memory for arrays so that there are no ArrayIndexOutOfBounds exceptions.

int *a = (int *) malloc( 10*sizeof(int) ); // ya ol' c
int *a = new int[10]; // c++
int[] a = new int[10]; // java
Copy the code

Yes, it’s actually creating an array of length 10. We don’t have sizeof in Javascript, but toString is enough to prove the point.

a.toString() // Return ",,,,,,,,,", which is equivalent to [,,,,,,,,,]
a / / / the empty x 10]
Copy the code

So, when passing a parameter to a new Array, it causes the JS engine to allocate space for the Array of the passed parameter size.

And this is also in the EcmaScript specification:

See, it’s not a contradiction. All descriptions are in the specification. We should always read the specifications of any language before drawing any conclusions.

Function constructor

Did you know that we can define Function using the Function constructor?

Do you understand? Let me be clear. In JavaScript, we define the following functions:

const mul = (a, b) = > a * b

/ / or
function mul(a, b) {
    return a * b
}

/ / or
const mul = function(a, b) {
    return a * b
}
Copy the code

We can also do this to achieve the same function:

const mul = new Function("a"."b"."return a * b")
Copy the code

The arguments passed to Function form the parameters and body of the Function. The variable mul becomes the function name.

Also, the last argument will be the body of the function, and the arguments before the last argument will be the arguments of the function.

In the MUL. “A” and “b” are the arguments that the function will receive, and “return a * b” is the body of the function. It multiplies “a” and “b” and returns the result.

We use muL (…) Call this function with the following arguments:

const mul = new Function("a"."b"."return a * b")

console.log(mul(7.8)) / / 56
Copy the code

According to the MDN:

The Function constructor creates a new Function object. Calling this constructor directly creates functions dynamically, but suffers security and relatively minor performance problems from EVAL. However, unlike eval, the Function constructor only runs in global scope.

5. Array deconstruction

We can decompose the elements of an array by using their index numbers.

const arr = [1.2.3]
Copy the code

The indexes of elements 1, 2, and 3 are 0, 1, 2, respectively, that is:

arr[0] / / 1
Copy the code

In everyday development, we most often use object deconstruction:

let o = {
    prop: 1
}
o["prop"] / / 1

/ / deconstruction
const {prop} = o
prop / / 1
Copy the code

So, we use deconstruction on arrays:

const arr = [1.2.3]
const { 0: firstA, 1: secA, 2: thirdA  } = arr

firstA / / 1
secA / / 2
thirdA / / 3
Copy the code

So we can use the index number to extract the element. An index is an attribute that defines the location of elements in an array.

const arr = [1.2.3]
Copy the code

Is equivalent to:

const arr = {
    0: 1.1: 2.2: 3.length: 3
}
Copy the code

Arrays are also objects, which is why they should be object decomposed, but there is a special syntax for array decomposition:

const [first, second, third] = arr

first / / 1
second / / 2
third / / 3
Copy the code

Note: You should avoid knowing specific positional information in an array (what the start and end indexes are) whenever possible.

Use the length attribute to reduce the contents of the array

The length attribute in an array represents the number of elements in the array.

const arr = [1.2.3]
arr.length / / 3
Copy the code

Reducing the value of the length attribute causes the JS engine to reduce the number of elements in the array to equal the value of the length attribute.

const arr = [1.2.3]
arr.length / / 3
arr.length = 1
arr / / [1]
Copy the code

The length attribute value of ARR is changed to 1, so arR reduces the number of elements to equal the length attribute value.

If the length attribute is increased, then the JS engine will add elements (undefined elements) so that the number of elements in the array reaches the length attribute value.

const arr = [1.2.3]
arr.length / / 3
arr.length = 1
arr / / [1]

arr.length = 5
arr // [1, empty × 4]
Copy the code

There is only one element in ARR, and then we increase the length to 5, so we add four more elements, bringing the number of elements to 5.

Seven, the Arguments

We can use the Arguments object to get the arguments passed to the function without explicitly defining arguments in the function:

function myFunc() {
    console.log(arguments[0]) / / 34
    console.log(arguments[1]) / / 89
}

myFunc(34.89)
Copy the code

The Arguments object is array indexed. That is, the property is a number and therefore accessible by key reference.

The Arguments object is instantiated from the Arguments class, which has some cool properties.

Arguments.callee. name specifies the name of the function that is currently being called.

function myFunc() {
    console.log(arguments.callee.name) // myFunc
}

myFunc(34.89)
Copy the code

The arguments. The callee. Caller. The name refers to the currently executing function called the name of the function.

function myFunc() {
    console.log(arguments.callee.name) // myFunc
    console.log(arguments.callee.caller.name) // myFuncCallee
}

(function myFuncCallee() {
    myFunc(34.89)
})()
Copy the code

This is particularly useful in the variadic function.

8, skip ()

Did you know that you can skip square brackets () when instantiating an object?

Such as:

class D {
    logger() {
        console.log("D")}}// In general, we do this:
(new D()).logger(); // D

// In fact, we can skip ():
(new D).logger(); // D
// And it works
Copy the code

Parentheses are optional even in built-in classes:

(new Date).getDay();
(new Date).getMonth();
(new Date).getYear();
Copy the code

Nine, void

Void is the key in JS that evaluates statements and returns undefined.

Such as:

class D {
   logger() {
        return 89}}const d = new D

console.log(void d.logger()) // undefined
Copy the code

The logger method should return 89, but the void keyword will invalidate it and return undefined.

I’ve read that undefined might be given another value before it, which would fake its semantics. Therefore, using the void operator ensures that you get a true undefined. Also used for minimization purposes.

Ten, through__proto__inheritance

_proto_ is a method that inherits properties from objects in JavaScript. __proto__ is the accessor property of object. prototype, which exposes the access to the Object’s [[prototype]].

This __proto__ sets all the properties of the object set in its [[Prototype]] to the target object.

Let’s look at an example:

const l = console.log
const obj = {
    method: function() {
        l("method in obj")}}const obj2 = {}
obj2.__proto__ = obj
obj2.method() // method in obj
Copy the code

We have two object constants: obj and obj2. Obj has the method attribute. Obj2 is an empty object constant, that is, it has no properties.

We access obj2’s __proto__ and set it to obj. This copies all the properties of OBj accessible through object.prototype to obj2. This is why we can call methods on Obj2 without getting an error if they are not defined.

Obj2 inherits the properties of OBj, so the method method properties will be available in its properties.

Stereotypes can be used with objects such as object constants, objects, arrays, functions, dates, RegEx, numbers, Booles, and strings.

11. The unary operator +

The unary + operator converts its operands to numeric types.

+"23" / / 23+ {}// NaN
+null / / 0
+undefined // NaN+ {valueOf: (a)= > 67 } / / 67
+"nnamdi45" // NaN
Copy the code

This is handy when we want to quickly convert a variable to a Number.

The unary operator –

Unary operator – Converts its operands to type Number and inverts them.

This operator inverts the result of the unary + operator. First, it converts the operand to its Number value, and then inverts that value.

-"23" / / - 23
Copy the code

What happens here is that the string “23” is converted to its numeric type, resulting in 23. This positive number is then converted to its negative form, -23.

- {}// NaN
-null / / - 0
-undefined // NaN- {valueOf: (a)= > 67 } / / - 67
-"nnamdi45" // NaN
Copy the code

If the result of the conversion to a numeric value is a NaN, the inverse is not applied.

If you take negative plus 0, you get negative 0. If you take negative minus 0, you get plus 0.

- +0 / / - 0
- 0 / / 0
Copy the code

Exponent operator **

This operator is used to specify the exponent of a number.

In mathematics, 2^3^ means multiplying 2 three times:

2 * 2 * 2
Copy the code

We can do the same thing in JS using the ** operator:

2天安门事件3 / / 8
9天安门事件3 / / 729
Copy the code

conclusion

Translated from 11+ JavaScript Features You’ve Probably Never Used

For more on this series,Go to the Github blog home page

Walking in the final

  1. ❤️ Have fun, keep learning, and always keep coding. 👨 💻

  2. If you have any questions or more unique opinions, please comment or directly contact The Bottle gentleman (the public number replies to 123)! 👀 👇

  3. 👇 welcome to pay attention to: front bottle gentleman, updated daily! 👇