This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.

At the beginning

With the advent of ES6+ and Typescript, the world of Javascript has become so full of symbols that it feels like you can’t keep up without a little hard work, and reading other people’s code is like reading a book from heaven.

Look at a function from a recent project, Em…… Call straight, dude!!

In order to move bricks more efficiently, this chapter explores some of the amazing symbols and notations that may be confusing you, but if you encounter something even more amazing, feel free to leave a comment in the comments section.

(All for the better touch fish, come on!!)

JS

Destruct assignment (written)

Destruct variable assignment is a new feature in ES6, it is a good thing, it is quite fun to use, it is very Nice!! I believe that you are familiar with it, so I will not explain the basic usage of it, but let’s take a look at the following interesting writing methods, and see if they can give you some new experience and learn some new skills.

The console solution

Debugging code is a very important link, although there are a variety of debugging methods, but used to use, or the console method is the simplest and most practical. Do you have a moment when writing console.log() is tedious? So you can try it a little bit like this:

({log: window.log, error: window.error, warn: window.warn} = console); The log (' normal '); Warn (' remind '); Error (' dangerous');Copy the code

It’s good to taste food by yourself

Arrays are special objects

Arrays are deconstructed by objects. How idle is that? (T_T)

var arr = ['L', 'O', 'V', 'E'];
var {0: l, 1: o, 2: v, 3: e} = arr;
console.log(l, o, v, e); // L O V E
Copy the code

Take the first and last term of the array

var arr = ['first', 'second', 'last'];
var {[0]: first, [arr.length - 1]: last} = arr;
console.log(first, last); // first last
Copy the code

This call what? This is called off the beaten track!! Wait, here we can find a little bit of knowledge, such as:

var arr = ['first', 'second', 'last'];
var {[arr.length <= 1 ? 0 : arr.length - 1]: last} = arr;
console.log(last); // last
Copy the code

Em… That’s a lot of things you can do with expressions, right? Hey hey!!

String is also deconstructed

var [a1, a2, a3, a4] = 'YYDS'; console.log(a1, a2, a3, a4); // Y Y D S var [lastname,...name] = 'c '; console.log(lastname, name); // Orange, person, front, endCopy the code

It may be used in few scenarios, but it may come in handy one day.

Variable value exchange

var x = 1;
var y = 2;
[x, y] = [y, x];
Copy the code

There’s nothing to be said for that, because you don’t have to define temporary variables anymore.

Default Value Default value

This is what I really saw in the project, roughly simplified like this, you can taste it carefully.

var upperValue = ''; / / the value of an interface let {value: newValue = upperValue | | 'on an interface no value'} = {value: undefined}; Console. log(newValue) console.log(newValue)Copy the code

Shakespeare said, “There are a thousand Hamlets in a thousand people’s eyes.”

I guess the same is true for code… (it’s even)

Template string label template (fn ‘ ‘)

Console. log 'orange someone'; // [' orange someone '] // equivalent to console.log([' orange someone ']); // [' orange ']Copy the code

This is actually a special form of calling a function, and although you may not use it in your lifetime, you can’t rule out how others might write it.

Numeric separator (_)

ES6 allows values to be delimited with an underscore (_), so you don’t have to worry about counting zeros anymore.

let num1 = 137_9083_7051; // Mobile phone number console.log(num1); // 13790837050 let num2 = 1_000_000_000; Console. log(num2); // 1000000000 let num3 = 1.000_000_000_1; // bit decimal console.log(num3); / / 1.0000000001Copy the code

The rest parameters (…).

Rest arguments (of the form… Variable name), which is used to receive the function’s superfluous arguments as an array.

function fn(val, ... vals) { console.log(val, vals); } fn(1, 2, 3, 4, 5); // 1 [2, 3, 4, 5]Copy the code

Arguments is a better alternative to arguments. Arguments are opaque, hidden, and can’t be used directly with array-dependent methods. Of course, more importantly, it can serve arrow functions. We know that arrow functions don’t have such arguments inside as this.

It can also be used not only with function arguments, but also with destructuring assignments:

var [a, ...rest] = [1, 2, 3, 4]; console.log(a); // 1 console.log(rest); / / [2, 3, 4]Copy the code

Rest parameters:

  • restThe parameter must be placed in the last digit of all parameters; otherwise, an error will be reported.
  • restArguments are not counted in the functionlengthProperties.
(function(a) {}).length // 1 (function(... a) {}).length // 0 (function(a, ... b) {}).length // 1Copy the code

Extended operators (…)

The extension operator is also a good thing, but it’s not the same as the REST argument, so don’t get confused.

console.log(... [1, 2, 3)); // 1 2 3 console.log({... {a: 1, b: 2, c: 3}}); // {a: 1, b: 2, c: 3} console.log([...document.querySelectorAll('div')]); // [div, div, div] console.log(... new Set([1, 2, 3])); // 1 2 3 console.log(... New Map([['name', 'orange '], ['age', 18]]); // ["age"] ["age", 18]Copy the code

The extension operator is easy to understand, easy to use, and very readable, but even then, you can’t stand the odd operation, and it’s easy to write mind-boggling ways.

console.log({... [' orange ', 'someone ',' person ']}); // {0: "orange ", 1:" x ", 2: "man "} console.log({... 'orange someone '}); // {0: "", 1:" ", 2: ""} function fn(... [a, b, c]) { console.log(a, b, c); } fn(1, 2, 3); // 1, 2, 3 fn(1, 2, 3, 4); // 1, 2, 3 are extension operators, not REST parametersCopy the code

Index operator (**)

The exponent operator (**) is the same thing as math.pow (), except it’s written more succinctly.

console.log(2 ** 2); // 2*2=4
console.log(2 ** 3); // 2*2*2=8
等同于
console.log(Math.pow(2, 2)); // 4
console.log(Math.pow(2, 3)); // 3
Copy the code

Just a little notice, though, that this guy is counting from the right:

console.log(2 ** 3 ** 2); // 2 ** (3*3) = 2 ** 9 = 2*2... = 512
Copy the code

Chain judgment operator (.?)

I don’t know if you’ve ever written something like this:

var response = {}
console.log(response && response.data && response.data.name); // undefined
Copy the code

In order to read a certain property inside the object console without error, we often need to determine whether the upper object of the property exists. This is no problem to write, but once the number of properties read, it becomes tedious to write. And here it is, ES2020 coming with the chain judgment operator.

console.log(response? .data? .name); // undefinedCopy the code

Isn’t that neat? That’s great. Is there any (-^ ○ ^-)?

The chain judgment operator works by determining whether the object on the left isnullundefined. If it is, it doesn’t go down, it goes backundefined.

Null judge operator (??)

Sometimes we need to determine if a variable is null, and if so, set the default value, otherwise, the original value. What would we say?

// var value = ''; // var value = 0; // var value = undefined; // var value = null; console.log(value ? Value: 'value is null '); // "and 0 also count as empty console.log(value! == undefined || value ! == null ? Value: 'value is null '); //Copy the code

ES2020I’ve introduced a new oneThe Null judgment operator ??, only the value to the left of the operator isnullorundefined, the value on the right is returned; otherwise, the value on the left is returned.

console.log(value ?? 'value not value);Copy the code

globalThis

JavaScript can run in different environments, such as browsers, workers, nodes, etc. Although they are all JS and have basically the same syntax, they have different global objects.

  • The browser global object is window.
  • Web WorkerThe global object isself.
  • NodeThe global object isglobal.

In this case, the ES2020 standard introduces globalThis in order to use uniform global objects in different environments.

// browser console.log(globalThis); // => Window {... } // node console.log(globalThis); // => Object [global] {... } // web worker console.log(globalThis); // => DedicatedWorkerGlobalScope {... }Copy the code

TS

After understanding the various symbols in JS, the next is some symbols in TS, but TS strange symbols are not many, most of them are the same as JS or evolved over, we will continue to look at the following.

(In order to show the error effect, the following code will basically use screenshots to replace, should also not code, are very simple code, the purpose is to explain the function and meaning of each symbol)

The non-empty assertion operator (!)

Json. This file is the TS configuration file. You can find it in the root directory of a typical TS project. You can also generate it actively with the NPX TSC –init command.

Then we need to open the “strictNullChecks”: true configuration item of the file. Why? Null and undefined are basic types in TS, with values null and undefined, respectively. By default, they are subtypes of all types, that is, they can be assigned to any type. When this option is turned on, they cannot be assigned to any other type, only to their own type.

Before opening the configuration item:

After the configuration item is opened:

“Nickname” is undefined and cannot be assigned to realname. Otherwise, an error will be reported. However, if there is some operation such that the nickname is already determined, for example:

How do we tell TS? What if it doesn’t report an error? This is where the non-null assertion operator comes in.

This way on the line, should also be relatively simple easy to understand it…

Optional attributes (? 🙂

Optional attributes This is a property of an interface, a very flexible concept that can be used to restrict an object, for example:

There is a human interface defined in the figure, including name, age and hobby, which can be used to limit objects. However, sometimes, some objects don’t have a hobby (well, it’s too bad that a person doesn’t have a hobby), and they can only report errors like Ming in the picture. How to do this?

This is where optional attributes of the interface can be used, such as:

Chain judgment operator (.?)

This operator has the same effect as the optional chain operator in the JS version and is simply an implementation of the TS version. Also check whether the object on the left is null or undefined. If so, it does not proceed further and returns undefined

var obj: any = undefined; if(obj? .name) {} // equivalent to if(obj && obj.name) {}Copy the code

The purpose of this is to prevent the console from reporting an error, because the obJ type may be unknown to us.

Null judge operator (??)

This operator has the same effect as the null value judgment operator in the JS version and is only implemented in the TS version. The value on the right of the operator is returned only if the value on the left of the operator is null or undefined, otherwise the value on the left is returned.

var value: string | undefined | null = ''; console.log(value ?? 'value is null '); // If value is null, the default value is usedCopy the code

Cross type operator (&)

This thing is like the operator and (&&), but it operates on the type definition, and it also has a single symbol (&). Using the crossover type operator, you can stack multiple types together to form a new type that contains all of the desired characteristics, but not all of them.

It can also be used on interfaces:

There’s nothing more to say, but there are some caveats to its use, such as this:

When two types that are crossed have the same property, but the property type definitions are different, the resulting type becomes never. This is because string & number obviously doesn’t exist, so it becomes never.

Joint type separators (|)

This also is very simple, and or (| |) function is similar, also is the same it is only a single symbol (|), but don’t write the wrong oh.

These examples are very simple and I won’t go into them. However, most of the time when using joint type separators, you encounter a class of problems, such as:

In the figure, whether we read name or age is not allowed in TS, TS cannot determine whether obj has these two attributes; There are many ways to solve this problem, which we call “type protection”. In fact, it is simple to understand that first determine the type of obJ object in the graph, and then proceed with the following operations.

(Here by the way a little mention of “type protection”, more content can go to the relevant information, we will point to stop)

Types of assertions

Type assertion is a bit of a cast thing, but not really, because it doesn’t cast, it just tricks TS type checking. There are two ways to write it, so let’s look at each of them.

TS does not allow us to assign an unknown type, or any other type, to a variable of an explicit type, but sometimes we have to do that, as in the case in the picture. How do we do that?

As grammar

< > syntax

Is that easy to understand?

A decorator (@ XXX)

What is a decorator? Remember, it’s essentially calling a function, it’s a syntax candy, no big deal. It allows you to add new functionality to an existing object without changing its structure.

To use it, you still have to open its related configuration item in tsconfig.json, which should be either “experimentalDecorators”: true or “emitDecoratorMetadata”: true.

Without further ado, let’s write a small example to observe and observe:

Function classFn(target: any) {console.log(' class decorator: ', target); } @classfn class Person{constructor() {console.log(' instantiate '); } } var p = new Person();Copy the code

This is what the console prints after execution:

Uh… This is similar to the Java decorator pattern. (it’s even)

Decorators can also pass arguments, and they are executed sequentially:

Function classFn(target: any) {console.log(' class decorator: ', target); return function(params: Any) {console.log(' Custom class decorator arguments: Class Person{constructor() {console.log(' instantiate ');}} @constructor () {constructor() {console.log(' instantiate '); } } var p = new Person();Copy the code

Decorators are not just class decorators, they have categories down:

  • Class decorators
  • Property decorators
  • Method decorators
  • Parameter decorators

Em…… There seems to be a lot of content involved, so I won’t introduce them one by one. I don’t want to bore you with too much content. The main purpose of this chapter is to take you to understand the various symbols, so as not to completely blind yourself when you take over the project. (ha ha ha, finally water over…… Escape, everyone is happy.








At this point, this article is finished, sa Hua Sa hua.

I hope this article has been helpful to you. If you have any questions, I am looking forward to your comments. Same old, likes + comments = you know it, favorites = you know it.