Var, let, const
Variable ascension
Variables can be declared after they are used, but they can be used because variables can be promoted
console.log(a) // undefined
var a = 1= = =var a
console.log(a) // undefined
a = 1
Copy the code
var a = 10
var a
consoleThe (a) ="var a
var a
a = 10
console.log(a)
Copy the code
Functions will also: var declarations will go up to the top, and functions will move the whole thing up
console.log(a) / / ƒ (a) {}
function a() {}
var a = 1="var a
function a() {}
console.log(a)
a=1
Copy the code
- Variables declared by var are mounted in the window, but let/const is not
- Let /const generates a temporary dead zone. Use referenceError before declaration
- Let and const work in much the same way, except that variables declared by the latter cannot be reassigned
- Let and const do not allow duplicate declarations
Why do we have variable promotion?
To solve the problem of functions calling each other
function test1() {
test2()
}
function test2() {
test1()
}
test1()
Copy the code
Because you can’t have test1 in front of test2 and test2 in front of test1.
My own summary of let and const implementations
Babel precedes let-defined variables with an underscore to prevent them from being accessed outside the block-level scope, which can also be simulated by self-executing functions
Proxy this value with Object.defineProperty() and set its writable to false to make it unmodifiable, although the proxy Object property value is modifiable
inheritance
Prototype chain inheritance
Disadvantages: Reference attributes are changed all instances are affected; The parameter cannot be passed when creating an instance
function Person(){}
functoin Child(){}
Child.prototype = new Person()
Child.prototype.constructor = Child
Copy the code
Constructor inheritance
Methods are created repeatedly within the constructor, resulting in excessive memory usage.
function Child(){Parent.apply(this,argument)}
function Child(id){
Parent.apply(this.Array.form(argument).slice(1);this.id = id;) }new Child(id,'xx')
Copy the code
Combination of inheritance
The above combination calls the constructor twice, duplicating the operation
When the parent class function is inherited, the parent class constructor is called, resulting in unnecessary parent class attributes on the prototype of the child class, and there is a waste of memory
Parent.prototype.eat = function () {
console.log(`The ${this.name} - eat`);
};
function Child(){Parent.apply(this,argument)}
Child.prototype = new Parent()
Child.prototype.constructor = Child
const child = new Child(1)
child.eat() / / 1
child instanceof Parent // true
Copy the code
Parasitic combinatorial inheritance
The disadvantage of composite inheritance is that the constructor is called when the parent function is inherited, and we just need to optimize this.
The core of the inheritance implementation above is to assign the prototype of the parent class to the child class, and set the constructor to the child class, which not only solves the problem of useless parent class attributes, but also can correctly find the constructor of the child class
function Child() {
Parent.apply(this.arguments);
}
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child
Copy the code
The class inheritance
class Parent {
constructor(value) {
this.val = value
}
getValue() {
console.log(this.val)
}
}
class Child extends Parent {
constructor(value) {
super(value)
}
}
Copy the code
The core of class implementation inheritance is the use of extends to indicate which Parent class it inherits from, and you must call super in the subclass constructor because this code can be viewed as parent.call (this, value).
There are no classes in JS. Classes are just syntactic sugar and are essentially functions.
class Person {}
Person instanceof Function // true
Copy the code
modular
Juejin. Cn/post / 684490…
Benefits:
- Resolving naming Conflicts
- Provide reusability
- Improve code maintainability
In the early
In the early days, functions were executed immediately to avoid naming conflicts and polluting global variables
(function(globalVariable){
globalVariable.test = function() {}
/ /... Declaring variables and functions does not pollute the global scope
})(globalVariable)
Copy the code
AMD and CMD
Use, define by require([‘moduleA’, ‘moduleB’], function(moduleA, moduleB) {}
The script file require.js that supports the specification needs to be introduced
Cannot run directly on node
// AMD
define(['./a'.'./b'].function(a, b) {
// The module can be used after loading
a.do()
b.do()
})
// CMD
define(function(require.exports.module) {
// Load the module
// You can write require anywhere in the function body for lazy loading
var a = require('./a')
a.doSomething()
})
//UMDIsomorphism, running in the browser and node.js at the same timemoduleIs there an environment to define and define, and how to define modules in a corresponding wayCopy the code
CJS
- use
// a.js
module.exports = {
a: 1
}
// or
exports.a = 1
// b.js
var module = require('./a.js')
module.a // -> log 1
Copy the code
Require simple principle:
var module = require('./a.js')
module.a
// Execute the function immediately, so as not to pollute the global variable,
// The important thing is module, which is a variable unique to Node
module.exports = {
a: 1
}
// module basic implementation
var module = {
id: 'xxxx'.I must know how to find him
exports: {} // exports is an empty object
}
Exports and module.exports are used in the same way
var exports = module.exports
var require = function (module) {
// Export things
var a = 1
module.exports = a
return module.exports
};
// Then when I require to find the unique id,
// Then the object to be used is wrapped in an immediate function that returns the exported object
// As far as I am concerned, I think so
map = {
./a.js:'1'
}
list = {
1:'a=1'
}
var require = fucntion(module){
/ / module for. / a. s
//return list[map[module]]
return module.exports
}
Copy the code
Exports and module.exports share the same address. Changing the property value of an object applies to both, but assigning an object directly to exports does not refer to the same memory address
ES module
ES Module is a modular solution implemented natively and differs from CommonJS in the following ways
- CommonJS supports dynamic import, namely require(${path}/xx.js), which is not currently supported but has been proposed
- CommonJS is a synchronous import, because it is used on the server, the files are local, and the synchronous import does not have much impact if the main thread is blocked. While the latter is asynchronous import, because for the browser, need to download the file, if also adopted synchronous import will have a great impact on rendering
- If the exported value changes, the imported value does not change, so if you want to update the value, you must import it again. However, the ES Module uses real-time binding. The import and export values point to the same memory address, so the imported value changes with the exported value
- ES Module is compiled to require/exports
// Import the module API
import XXX from './a.js'
import { XXX } from './a.js'
// Export the module API
export function a() {}
export default function() {}
Copy the code
More complete difference: mp.weixin.qq.com/s/TbwDzQcW8…
1.Different loading modes are used`require()` 和 `module.exports`or`exports`Attribute assignment of; ESM using`import` 和 `export (defalut)`, can be loaded on demand;2.Different operating mechanisms In ES6, when the JS engine performs static analysis on scripts, the module is loaded with a read-only reference, which cannot be assigned a value. Wait for the script to actually execute to load the module asynchronously, get the value from the module by reference, because of the reference import, the internal value of the module changes will affect the external value of the import CJS is synchronous load at runtime,requireThe file is read from the hard disk, and the code is immediately executed. The output is a copy of the value, and CJS caches the module's results3.Different operating environments CJS mainly runs on the server side. CJS is the Node modular specification. Esm mainly runs on the browser side, JS-core level4.When two files are interdependent, esM interrupts execution and reports a reference error. CJS suspends execution without error; cjsthisPoints to the current module, es6 points to the undefind CJS use`require()` 和 `module.exports`or`exports`Attribute assignment of; ESM using`import` 和 `export`The CommonJS module prints a copy of the value, the ES6 module prints a reference to the value. CJS is loaded at runtime,requireIt reads from the hard drive and immediately executes the code,module.exports is generated when the script runs. ESM module loading is asynchronous, compile-time output interface, that is, the JS engine static analysis of the script to obtain a read-only reference, the code is asynchronously downloaded during execution, the code is downloaded in parallel, but in order to execute. ESM is js core level, the other is the runtime environment specificationCopy the code
proxy
Get read, set set, from the property in Object, delete to delete objects, ownKeys interception Object. GetOwnPropertyNames (proxy), the Object. The keys (proxy), for… The in loop also intercepts other methods on Object prototypes, intercepts operations on Proxy instances as function calls and constructor calls, and calls call, apply, and new
Advantages: Better performance and effect, poor compatibility
Function:
Custom object operations, used by Vue3.0 for data response
How is VUe3 set
let onWatch = (obj, setBind, getLogger) = > {
let handler = {
get(target, property, receiver) {
getLogger(target, property)
return Reflect.get(target, property, receiver)
},
set(target, property, value, receiver) {
setBind(value, property)
return Reflect.set(target, property, value)
}
}
return new Proxy(obj, handler)
}
let obj = { a: 1 }
let p = onWatch(
obj,
(v, property) = > {
console.log('Listens on properties${property}Change for${v}`)},(target, property) = > {
console.log(` '${property}'=${target[property]}`)
}
)
p.a = 2 // Listen for attribute A change
p.a // 'a' = 2
get(target, property, receiver) {
getLogger(target, property)
// This judgment code is new
if (typeof target[property] === 'object'&& target[property] ! = =null) {
return new Proxy(target[property], handler);
} else {
return Reflect.get(target, property); }}Copy the code
map, filter, reduce
What a map does is it creates a new array, iterates through the old array, takes each element and does some transformation and puts it in the new array.
[1, 2, 3]. Map (v => v + 1) // -> [2, 3, 4
['1'.'2'.'3'].map(parseInt)
parseInt(String, radix) Resolves the characters, radix: several bases, between2 ~ 36In between. If this parameter is omitted or its value is0, the number will be10To analyze on the basis of. If it starts with "0x" or "0x", it will be16As the base.parseInt('11'.2) = >3If the parameter is less than2Or greater than36,parseInt() will returnNaN. First iterationparseInt('1'.0) - >1Second round of traversalparseInt('2'.1) - >NaNThe third iterationparseInt('3'.2) - >NaN
Copy the code
Filter is also used to generate a new array and add elements that return true to the array while iterating through the array. We can use this function to remove unwanted elements
let array = [1.2.4.6]
let newArray = array.filter(item= >item ! = =6)
console.log(newArray) / / [1, 2, 4]
Copy the code
Like Map, filter’s callback takes three arguments and is equally useful.
- reduce
Juejin. Cn/post / 684490…
If we want to implement a function that adds up all the elements of the function to get a value
const arr = [1.2.3]
const sum = arr.reduce((acc, current) = > acc + current, 0)
console.log(sum)
Copy the code
For Reduce, which takes two parameters, a callback function and an initial value, let’s break down the reduce process in the code above
The initial value is 0, which is passed in as the first argument when the first callback is executed
The callback function takes four arguments: cumulative value, current element, current index, and original array
On one callback, the current value and the initial value add up to 1, which is passed in as the first argument on the second callback
So the second time the callback is executed, the values add up to 1 and 2, and so on, and the result is 6
Reduce can also do a lot of other things. Let’s use Reduce to implement the map function
const arr = [1.2.3]
const mapArray = arr.map(value= > value * 2)
const reduceArray = arr.reduce((acc, current) = > {
acc.push(current * 2)
return acc
}, [])
console.log(mapArray, reduceArray) / / (2, 4, 6]
Copy the code
- This article is part of the “Gold Nuggets For Free!” Event, click to view details of the event