Hello, I’m the pointer. Winter is coming, people also become lazy, in order to let oneself move, I signed up for the hook education of the big front salary training camp. Learning needs summary, need to share, need to spur, so there is a “needle love learning front” this series, I hope you can have harvest after reading. If there is something wrong in the article, I hope you can criticize and correct me!!
ECMAScript
0. Chatting
To be honest, ES6 has been around for a long time, but I find in my work that many people still don’t use some of the new features in ES6 to optimize their code. As a helpful elder brother, I am worried, heart, heart is like, so hastily wrote this article, I hope you can have the harvest, if the bosses also hope to supplement their own point of view, after all, I a person baidu to hard finishing also has great may not be comprehensive, pointer in this thank humbly. (This article is not intended to be a comprehensive introduction to ES6, but rather an introduction to some of the advantages that ES6 can provide us at work.)
1. What is ECMAScript
ECMAScript is a scripting language standardized by Ecma International (formerly the European Computer Manufacturers Association) through ECMA-262. This language is widely used on the World Wide Web and is often referred to as JavaScript or JScript, but the latter two are actually implementations and extensions of the ECMA-262 standard. Simply put, ECMAScript is the international standard for the JavaScript language, and JavaScript is the implementation of ECMAScript.
JS is an extension of ES. It extends the ES syntax, allowing it to manipulate DOM and BOM in the browser environment, read and write files in the Node environment, and so on.
In a Web environment, ES + Web API (BOM,DOM manipulation) is JS
In a Node environment, ES + NodeApI(fs,net,etc.) is JS
2. Whatever else, use it first
The saying that practice makes perfect is applicable everywhere. Most of the time, when you look at something, you cannot remember it. You have to use it, and it becomes your habit when you use it.
The es6 is 2016, and now it’s 2021. Can I learn from it? Don’t worry, they decided to make a new version of es6 because they were afraid people wouldn’t be able to learn it, so they dropped the version number, and each new version was named after ECMAScript plus the year, so es6 was actually released in 2015.
2.1 Optimization of declared variables (let, const)
I’m sure you’ve been tortured by the variable improvement questions caused by VAR, so promise me that you won’t be the person you hate the most, okay?
// Let introduces the third scope in JS, block-level scope. Variables declared by lets can only be used in block-level scopes
// In the past, the variable declared by var can be used before it is declared. It is just undefined, which is a little bit wrong, but in let, there is no such problem. The variable defined by let can be used before it is declared. The variable is not available until it is declared using the let command. This is grammatically called a temporary dead zone (TDZ).
console.log(a) // undefined
var a = 1
console.log(a2) // ReferenceError: Cannot access 'a2' before initialization
let a2 = 2
----------------------------------------------------------------------------
// Let has helped me most at work when using the for loop
// We use the for I loop just to get the I, but we often run into this problem before let comes out
// Because the for loop is synchronous, when there is asynchronous code inside the loop, because the for loop has completed, I is all 5
for(var i = 0; i < 5; i++) {
setTimeout(() = > {
console.log(i)
}, 0)}// 5
// But let can generate a block-level scope in which I is invariant
// Loop 5 times to generate 5 block-level scopes, with each scope's I not affected by each other
for(let i = 0; i < 5; i++) {
setTimeout(() = > {
console.log(i)
}, 0)}// 0 1 2 3 4
----------------------------------------------------------------------------
// Let variables can also not be declared twice, in case the variable declared later overwrites the previous one
var a = 1
var a = 2
let b = 1
let b = 2 // SyntaxError: Identifier 'b' has already been declared
----------------------------------------------------------------------------
// Block-level scopes must be wrapped around {}, so some neat notation like if does not generate block-level scopes
let a = 1
if(true) let a = 2 // SyntaxError: Lexical declaration cannot appear in a single-statement context
// This is ok
if(true) {
let a = 2} -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -// Const is much like let, but it defines a constant
// Const variables must be assigned at definition and cannot be changed
// But by immutable, we mean immutable memory addresses, so objects and arrays are fine as long as they do not change the memory pointing of variables
const a; // SyntaxError: Missing initializer in const declaration
const a = 1;
a = 2; // TypeError: Assignment to constant variable.
const obj = {}
obj.name = "zhizhen" // Yes, because the memory pointing of obj is not changed
obj = {} // TypeError: Assignment to constant variable. Reassigning obj changed the memory orientation, so no
Copy the code
2.2 Optimization of declaring multiple variables at the same time (Deconstructing assignment)
It’s very easy to deconstruct assignment. How to use it
If the name is symmetric, it is undefined
// Common optimization
let a = 1;
let b = 2; = >let [a, b, c] = [1.2.3]
let c = 3;
----------------------------------------------------------------------------
// Array nested structure
let arr = ["zhizhen"["male"."hanson"."clever"]]
let [name, nature] = arr
console.log(name) // "zhizhen"
console.log(nature) // ["male", "hanson", "clever"]
----------------------------------------------------------------------------
// Destruct assignment of an object, usually used when importing a third party library
// This imports the curry method of lodash's FP module
const { curry } = require("lodash/fp") -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -// Object nesting
let res = {
code: 200.data: ["Merci"."Zoey"].message: "success"
}
let { code, data, message1 } = res
console.log(code) / / 200
console.log(data) // ["Merci", "Zoey"]
console.log(message1) // undefined
----------------------------------------------------------------------------
// Optimize assignment in bubble sort
let array=[3.6.2.2.5.7.8.1];
let length = array.length
for (let i = 0; i < length - 1; i++){
for (let j = 0; j < length - 1 - i; j++) {
if (array[j] > array[j + 1]) {
// let temp = array[j];
// array[j] = array[j + 1];
// array[j + 1] = temp;
[array[j], array[j+1]] = [array[j+1], array[j]]
}
}
}
----------------------------------------------------------------------------
// Implement the function's named arguments (similar)
function fn({ x, y, z }) {
console.log(x, y, z)
}
fn({ x: 1.y: 2.z: 3 })
Copy the code
2.3 String Concatenation Optimization (Template String)
let a = "hello"
let b = "zhizhen"
/ / before
let c = a + b + "l love you"
/ / now,
// Use ' 'to wrap the entire string. Use ${} to wrap arguments
// ' 'can be directly newline
let c2 = `${a} ${b} l love you`
Copy the code
2.4 Some methods for strings
/ / the includes, startsWith, endsWidth is the query string contains a character, return a bool value
// The padStart and padEnd methods are used to complete a given value at the head or end of a string
let num = 5
let str = num.toString(2)
console.log(str); / / 101
console.log(str.padStart(32.0)); / / 00000000000000000000000000000101
Copy the code
2.5 Some optimizations of functions
// Arrow function
// No, no, no, no one can't use arrow functions in 2021
// => The biggest feature is that, instead of having its own this, external this is used
// This avoids many of the problems caused by this pointing
let fn = (value) = >{} -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -// fn.length gets the number of function arguments that do not have default values
function myCurry(fn) {
return function curryFn() {
if(arguments.length < fn.length) {
let arr = Array.from(arguments)
return function () {
let arr2 = Array.from(arguments)
return curryFn.apply(this, arr.concat(arr2))
}
}
return fn.apply(null.arguments)}} -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -The rest argument is used to get extra arguments to a function in place of the arguments object. This way we can optimize the code above
function myCurry(fn) {
return function curryFn(. args) {
if(args.length < fn.length) {
return function(. args2) {
returncurryFn(... args.concat(... args2)) } }returnfn(... args) } }// Rest stands for residual arguments, so if there are other arguments in the method, rest comes last
function fn(a, ... rest) {
console.log(rest)
}
fn(1.2.3.4.5) // [2, 3, 4, 5]
Copy the code
2.6 Some optimization methods for arrays
// The same REST method, called the extension operator, converts an array to a comma-separated sequence of arguments
// Can be used to generate arrays, copy arrays, merge arrays
let arr = [1. arr2]let arr2 = [...arr]
let arr3 = [...arr, ...arr2]
----------------------------------------------------------------------------
// array. from converts a pseudo-array to an Array. Es5 array.slice. call(arrayLike)
// Array.from can also take a second argument, similar to the map method
function fn() {
let arr = Array.from(arguments.(value) = > value + 1)
console.log(arr)
}
fn(1.2.3) / / 2 and 4
----------------------------------------------------------------------------
// find and findIndex are both used to find matching array members
// includes determines whether the array contains a value
// filter Filter array
// map iterates through the array and returns a new array by performing some operations
For (let I = 0; i
let arr = [1.2.3]
let has3 = arr.find(item= > item == 3)
console.log(has3); / / 3
let has1 = arr.findIndex(item= > item == 1)
console.log(has1); / / 0
let has2 = arr.includes(2)
console.log(has2); // true
let arr2 = arr.filter(item= > item > 1)
console.log(arr2); / / [2, 3]
let arr3 = arr.map(item= > item+1)
console.log(arr3); / / [2, 3, 4]
Copy the code
2.7 Some optimizations of objects
// If the variable name is the same as the attribute name, you can abbreviate it
// You don't have to write this way, but you have to recognize it
let x = "hello"
let foo = { let foo = {
x: x= > x
} }
// The method can also be abbreviated
let foo = {
sayHello: function () {}} = >let foo = {
sayHello(){}} -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -// Use the [] expression as the attribute name
let a = "hello"
let b = "sayHello"
let foo = {
[a]: "aaaa",
[b]() {
}
}
----------------------------------------------------------------------------
// Object traversal
Object.keys(obj) // The Symbol attribute and the non-enumerable attribute are not included in the return
Object.getOwnPropertyNames(obj) Non-enumerable attributes are not included in the return
Reflect.ownKeys(obj) // All attributes are returned
----------------------------------------------------------------------------
// Object.assign(target, obj1, obj2...) Object to merge
// The first parameter is the target parameter, the following are the merged objects, if there is a parameter with the same name, will use the same parameter in the following obj
let obj1 = {
a: 111.b: 222
}
let obj2 = {
a: "Obj2 a.".c: 333
}
Object.assign(obj1, obj2)
console.log(obj1); {a: 'a' of obj2, b: 222, c: 333}
Copy the code
2.8 the asynchronous invocation (Promise, the Generator, async/await)
To be honest, in my limited working life, I’ve never seen callback hell, because I haven’t had that many layers of callback hell, and I usually solve them with callback. But Promise, new ways to handle asynchronous calls, you don’t have to use them, but someone else wrote them, so you have to understand them. Much of do not say, see me before two period article know 😀
The 2.9 class class generates constructors
In the past, the constructor used to generate instance objects, but it is too uncomfortable to write, so there is a class syntax sugar, comfortable to use, you do not have to know the class, you say the following several kinds of understanding, I think work enough use
- Basic use of class
// 1. Use the class keyword to generate a class named People
// 2. The constructor method accepts arguments and declares instance attributes of the class
The class constructor is executed when an instance object is new
// 4. Declare the instance attribute without the constructor (update node if there is an error)
/ / 5. Declare an instance method, do not need to add in front of the function, is equivalent to the People. The prototype. SayHello = function () {}
// 6. Methods and methods, methods and attributes do not need to add,
Static attributes can only be used in static methods, which are called directly by the class
class People {
constructor(name, age) {
this.name = name
this.age = age
console.log("People constructor implementation");
}
status = "health"
sayHello() {
console.log(`my name is The ${this.name}, I amThe ${this.status}`)}static print() {
console.log("i am static fn")}static gender = "male"
}
let p = new People("Pointer"."18")
p.sayHello() // My name is pointer, I am health
People.print() // i am static fn
Copy the code
- The class inheritance
// 1. Extends using the extends keyword
// 2. The constructor can accept other parameters, which are its own parameters
// 3. The super constructor is executed first, because the parent constructor must be executed before the property method is inherited
// 4. Declare your own attributes and methods
// 5. Static methods are inherited
class Student extends People {
constructor(name, age, homework, homework2) {
super(name, age)
this.homework = homework
this.homework2 = homework2
console.log("Student constructor execution")}doHomeWork() {
console.log(` I love to doThe ${this.homework}, as well asThe ${this.homework2}`)}}let stu = new Student("Merci"."18"."Three"."The Queen's Plan")
stu.sayHello() // my name is Merci, i am health
stu.doHomeWork() // I love to do 53s and the Queen's lesson plan
Student.print() // i am static fn
Copy the code
- Class simulates abstract classes using new.target
// New. target is an internal Class call that returns the current Class
// When a subclass inherits its parent Class, new.target returns the subclass Class
// Let's emulate an abstract class with this feature
class People {
constructor() {
if (new.target === People) {
throw new Error("Abstract classes cannot be instantiated")}}}Copy the code
2.10 Set to handle array deduplication
I’m only going to use this property for Set, so if you have anything else, let me know in the comments
// Set is a class array, but the members are unique, we use this feature to implement array de-duplication
// Use a new Set to convert the array to a Set with no duplicates
// Use arrry. from to convert Set to array
let arr = [1.2.3.2.3.4.1]
arr = new Set(arr)
console.log(arr); // Set(4) { 1, 2, 3, 4 }
arr = Array.from(arr)
console.log(arr); // [1, 2, 3, 4]
Copy the code
2.11 the Proxy and Reflect
Because Vue now uses Proxy to do data hijacking, I think the interviewer will definitely ask, so Proxy you need to know, and Vue used Object. DefineProperty, I think you should also know the difference between the two
The object.defineProperty method has three drawbacks, which you can tell from its entry
// The first argument is the object, the second is the object attribute, and the third is the definition description
// So the three disadvantages are:
// 1. Cannot listen for array changes
// 2. You can only listen for a single property change of an object. If you want to listen for an object, you need to traverse the listener
// 3. If the object property is still an object, deep traversal is required to listen
Object.defineProperty(obj, prop, descriptor)
// Let's look at the Proxy entry
// The first argument is an object of any type, and the second argument is a definition description
// The Proxy listens for the entire Object, avoiding the drawbacks of Object.defineProperty
new Proxy(target, handler)
// Proxy defines 13 methods (for those interested)
// Change this to the target object
Proxy.apply(target, thisArg, args)
// Call the constructor
Proxy.construct(target, args)
// Find the properties of the object
Proxy.get(target, name, receiver)
// Set the properties of the object
Proxy.set(target, name, value, receiver)
// Define attributes for the object
Proxy.defineProperty(target, name, desc)
// Delete object properties
Proxy.deleteProperty(target, name)
// Determine if the object contains an attribute
Proxy.has(target, name)
// Returns all attributes of the object
Proxy.ownKeys(target)
// Indicates whether the object is extensible
Proxy.isExtensible(target)
// Make the object unextensible
Proxy.preventExtensions(target)
// Get the description object of the specified property
Proxy.getOwnPropertyDescriptor(target, name)
// Reads the __proto__ attribute of the object
Proxy.getPrototypeOf(target)
// Set the prototype of the object
Proxy.setPrototypeOf(target, prototype)
Copy the code
Reflect also defines 13 methods, corresponding to Proxy one by one. Reflect actually aims to unify methods related to the object, and unify all methods of the object into the form of Reflect.xxx, which is convenient for everyone to remember. In fact, each method can find an alternative method.
Reflect.apply(target, thisArg, args) => Object.prototype.toString.call(youngest)
Reflect.construct(target, args) => new MyClass()
Reflect. Get (target, name, receiver) => Is the object. The property nameReflect.set(target, name, value, receiver) => obj.xx = XXXReflect.defineProperty(target, name, desc) => Object.defineProperty
Reflect.deleteProperty(target, name) => delete obj.xx
Reflect.has(target, name) => key in obj
Reflect.ownKeys(target) => Object.getOwnPropertyNames + Object.getOwnPropertySymbols
Reflect.isExtensible(target) => Object.isExtensible
Reflect.preventExtensions(target) = Object.preventExtensions
Reflect.getOwnPropertyDescriptor(target, name) => Object.getOwnPropertyDescriptor
Reflect.getPrototypeOf(target) => Object.getPrototypeOf(obj)
Reflect.setPrototypeOf(target, prototype) => Object.setPrototypeOf(obj)
Copy the code
2.12 Symbol
I have not used this in my work, only know is js new data type, can generate a non-repeatable value, so in modularization can prevent the later method overwriting the previous method. I haven’t used it in my work, so let’s just understand it.
3. I will write here for now. If you have anything I haven’t written, please leave a comment and let me know
navigation
The needle to learn front-end | JavaScript depth excavation of functional programming
Needle to learn front-end | JavaScript depth excavation of asynchronous programming
Needle to learn front-end | JavaScript depth excavation of written Promise
The needle to learn ECMAScript front-end | JavaScript depth excavation
reference
All the above materials are provided by the hook education training camp 😀