Written in the beginning
- ES6 common but ignored methods series of articles, sorting out the author thinks that some daily development may use some methods, use skills and some application scenarios, details please see related content links, welcome to supplement exchange.
Related articles
- Common but overlooked methods for ES6 (Destruct assignments and values first)
- ES6 Common but ignored methods (second bullet functions, arrays, and objects)
- ES6 common but ignored methods (third bullet Symbol, Set, and Map)
- ES6 commonly used but overlooked methods (fourth bullet Proxy and Reflect)
- ES6 common but ignored methods (# 5 Promise and Iterator)
- Common but ignored methods for ES6 (Generator 6)
- ES6 Common but ignored methods (async)
- ES6 Common but ignored methods (eighth bullet Class)
- Common but ignored methods of ES6 (Development specification of the Tenth Bullet Project)
- ES6 common but ignored method (eleventh bullet Decorator)
- Common but overlooked approaches to ES6 (End game – Latest Proposal)
Module
- ES6-Module
CommonJS
和AMD
Modules can only determine these things at run time.ES6
Modules can be loaded at compile time, which is much more efficientCommonJS
Modules are loaded in a high way, called “compile-time loading” or static loading.- advantage
- Can further broaden
JavaScript
Syntax, such as introducing macros (macro
) and type checking (type system
) functions that can only be implemented by static analysis. - No longer need
UMD
Module format. - A new browser for the future
API
It can be provided in module format and no longer has to be a global variable ornavigator
Object properties. - Objects are no longer required as namespaces (e.g
Math
Object), and in the future these functions could be provided through modules.
- Can further broaden
Strict mode
ES6
The module automatically adopts strict mode, whether you add it to the module header or not"use strict"
.- Limitations:
- Variables must be declared before being used
- Function arguments cannot have attributes of the same name; otherwise, an error is reported
- You can’t use
with
statements - Cannot assign a value to a read-only attribute, otherwise an error is reported
- Can’t use prefixes
0
Represents an octal number, otherwise an error is reported - You cannot delete attributes that cannot be deleted; otherwise, an error is reported
- Cannot delete variables
delete prop
, an error is reported, and only attributes can be deleteddelete global[prop]
eval
No variables are introduced in its outer scopeeval
andarguments
Cannot be reassignedarguments
Does not automatically reflect changes in function parameters- You can’t use
arguments.callee
andarguments.caller
- ban
this
Pointing to a global object - You can’t use
fn.caller
andfn.arguments
Gets the stack of function calls - Added reserved words (e.g
protected
,static
andinterface
)
- Note in particular the limitation of this.
ES6
In modules, at the top levelthis
Point to theundefined
That is, should not be used in top-level codethis
.
The export command
export
Command is used to specify the external interface of a module.- A module is an independent file. All variables inside the file are not available externally. You must use this function if you want outsiders to be able to read a variable inside the module
export
Keyword output the variable. In addition to output variables, you can also output functions or classes (class
).
// index.js export const name = 'detanx'; export const year = 1995; export function multiply(x, y) { return x * y; }; // const name = 'detanx'; const year = 1995; function multiply(x, y) { return x * y; }; export { name, year, multiply }Copy the code
export
The output variable is the original name, but can be usedas
The keyword is renamed. After the rename, you can print it multiple times with different names.
function v1() { ... }
function v2() { ... }
export {
v1 as streamV1,
v2 as streamV2,
v2 as streamLatestVersion
};
Copy the code
export
Commands specify external interfaces and must establish a one-to-one correspondence with variables inside the module.
Export 1; var m = 1; export m; Export var m = 1; var m = 1; export {m}; var n = 1; export {n as m};Copy the code
export
Commands can appear anywhere in the module, as long as they are at the top of the module.export *
Commands ignore modulesdefault
Methods.
// export * from 'my_module';Copy the code
The import command
- use
export
Command defines the external interface of the module, and otherJS
The file can go throughimport
Command to load the module. To give the input variable a new name,import
Command to useas
Keyword to rename the input variable.
import { name, year } from './index.js';
import { name as username } from './profile.js';
Copy the code
- The variables entered by the import command are read-only because it is by nature an input interface. That is, it is not allowed to rewrite interfaces in scripts that load modules. If a is an object, overwriting a’s properties is allowed.
import {a} from './xxx.js' a = {}; // Syntax Error : 'a' is read-only; a.foo = 'hello'; // It is validCopy the code
import
At the back of thefrom
Specifies the location of the module file, which can be relative or absolute..js
The suffix can be omitted. If it is just the module name with no path, then there must be a configuration file (e.gwebpack
Configure the path), tellsJavaScript
Engine position of the module.
import {myMethod} from 'util';
Copy the code
import
Commands are promoted to the head of the module and executed first.
foo(); Import {foo} from 'my_module';Copy the code
import
It executes statically, so you can’t use expressions and variables, which are syntactic structures that only get results at run time.
Import {'f' + 'oo'} from 'my_module'; // let module = 'my_module'; import { foo } from module; If (x === 1) {import {foo} from 'module1'; } else { import { foo } from 'module2'; }Copy the code
- Repeat the same sentence many times
import
Statement, then it is executed once, not multiple times.
import 'lodash'; import 'lodash'; Import {foo} from 'my_module'; import { bar } from 'my_module'; // Equivalent to import {foo, bar} from 'my_module';Copy the code
Overall loading of modules
- Instead of specifying an output value to load, you can also use the whole load, using the asterisk (
*
) specifies an object to which all output values are loaded.
import * as user from './index.js'; user.name; // 'detanx' user.year; / / 1995Copy the code
Export the default command
export default
Command to specify default output for the module. When other modules load this module,import
Command (import
You can specify any name for this anonymous function.
// export-default.js
export default function () {
console.log('detanx');
}
// import-default.js
import customName from './export-default';
customName(); // 'detanx'
Copy the code
- use
export default
, corresponding toimport
Statements do not need braces; useexport
, the correspondingimport
The statement requires braces.A module can only have one default output, soexport default
The command can be used only once.
export default function crc32() { ... } import crc32 from 'crc32'; export function crc32() { ... }; import { crc32 } from 'crc32';Copy the code
A compound of export and import
- If you input and then output the same module in a module,
import
Statements can be associated withexport
Statements written together.So when I write a line,foo
andbar
It is not actually imported into the current module, but merely forwards the two interfaces so that the current module cannot be used directlyfoo
andbar
.
export { foo, bar } from 'my_module'; Import {foo, bar} from 'my_module'; export { foo, bar };Copy the code
- The interface name and overall output of a module can also be written in this way.
Export {foo as myFoo} from 'my_module'; // export * from 'my_module';Copy the code
- The default interface is written as follows.
export { default } from 'foo';
Copy the code
- The named interface is changed to the default interface as follows.
export { es6 as default } from './someModule'; // Import {es6} from './someModule'; export default es6;Copy the code
- Similarly, the default interface can be renamed to a named interface.
export { default as es6 } from './someModule'; Before ES2020, there was an import statement with no corresponding compound. import * as someIdentifier from "someModule";Copy the code
ES2020
I’ve made up this notation.
export * as ns from "mod"; Import * as ns from "mod"; export {ns};Copy the code
application
- Public module
- For example, a project has many public methods put into one
constant
We load whatever we need.
// Constants. Js module export const A = 1; export const B = 3; export const C = 4; // use.js import {A, B} from './constants';Copy the code
- For example, a project has many public methods put into one
- import()
import
Command will beJavaScript
Engine static analysis, executed before other statements in the module (import
The command is called “Connect”binding
More appropriate). So we can only use it at the top level.ES2020
The introduction ofimport()
Function to support dynamic loading of modules.import()
Returns aPromise
Object.
const main = document.querySelector('main'); import(`./section-modules/${someVariable}.js`) .then(module => { module.loadPageInto(main); }) .catch(err => { main.textContent = err.message; }); Copy the code
import()
Functions can be used anywhere, not just in modules, but also in non-module scripts. It is run time execution, that is, whenever this sentence is run, the specified module is loaded. In addition,import()
Unlike import statements, functions are not statically linked to loaded modules.import()
Similar to theNode
的require
Method, the main difference is that the former is asynchronous loading, the latter is synchronous loading.- Application Scenario Modules are loaded on demand, conditionally loaded, and dynamically.
- Pay attention to the point
import()
Once the module is successfully loaded, the module is treated as an objectthen
Method parameters. Therefore, you can use the syntax of object deconstruction assignment to get the output interface.
import('./myModule.js') .then(({export1, export2}) => { // ... });Copy the code
- In the code above,
export1
andexport2
Are allmyModule.js
The output interface can be deconstructed. - If the module has
default
Output interface, can be obtained directly with parameters.
import('./myModule.js') .then(myModule => { console.log(myModule.default); }); Copy the code
- The above code could also use named input.
import('./myModule.js') .then(({default: theDefault}) => { console.log(theDefault); }); Copy the code
- If you want to load multiple modules at the same time, you can write the following.
Promise.all([ import('./module1.js'), import('./module2.js'), import('./module3.js'), ]) .then(([module1, module2, Module3]) => {···});Copy the code
import()
Can also be used inasync
Delta function.
async function main() { const myModule = await import('./myModule.js'); const {export1, export2} = await import('./myModule.js'); const [module1, module2, module3] = await Promise.all([ import('./module1.js'), import('./module2.js'), import('./module3.js'), ]); } main(); Copy the code
Module loading implementation
- Es6-module load implementation
Introduction to the
- Traditional load
- By default, browsers load synchronously
JavaScript
The script that the rendering engine encounters<script>
The tag will stop, wait until the script is finished, and then continue rendering down. In order to solve the<script>
TABdefer
orasync
Property, the script will load asynchronously. defer
withasync
The difference between:defer
Wait until the entire page is properly rendered in memory (DOM
Structure is fully generated, and other scripts are executed).async
Once the download is complete, the rendering engine interrupts the rendering, executes the script, and continues rendering. In a word,defer
It’s “render before you execute”,async
It’s “Execute as you download”. In addition, if there are multipledefer
Scripts are loaded in the order they appear on the page, and multipleasync
Scripts do not guarantee the load order.
- By default, browsers load synchronously
- Load the rules
- Browser loading
ES6
Module, also used<script>
Tag, but addtype="module"
Properties. It’s the same thing as turning it on<script>
Of the labeldefer
Properties.
<script type="module" src="./foo.js"></script> <! - equivalent to -- > < script type = "module" SRC = ". / foo. Js "defer > < / script >Copy the code
- There are a few things to note about external module scripts.
- Code is run in module scope, not global scope. The top-level variable inside the module is not visible outside.
- Module scripts automatically adopt strict mode, declared or not
"use strict"
. - Module, can be used
import
Command to load other modules (.js
Suffixes cannot be omitted; they need to provide the absoluteURL
Or relativeURL
), can also be usedexport
Command output external interface. - In modules, at the top level
this
Keyword returnundefined
Instead of pointingwindow
. That is, at the top of the modulethis
Keywords are meaningless. - If the same module is loaded more than once, it is executed only once.
import utils from 'https://example.com/js/utils.js'; const x = 1; console.log(x === window.x); //false console.log(this === undefined); // true Copy the code
- Utilizing top-level
this
Is equal to theundefined
This syntax point detects whether the current code is inES6
Module.
const isNotModuleScript = this ! == undefined;Copy the code
- Browser loading
Differences between ES6 modules and CommonJS modules
- discuss
Node.js
loadingES6
Modules must be understood beforeES6
Module andCommonJS
Modules are completely different. - There are two important differences.
CommonJS
The module outputs a copy of the value,ES6
A module outputs references to values.CommonJS
Modules are loaded at runtime,ES6
A module is a compile-time output interface. (because theCommonJS
An object is loaded (i.emodule.exports
Property), which is generated only after the script has run. An ES6 module is not an object, and its external interface is a static definition that is generated during the code static parsing phase.
CommonJS
A module outputs a copy of a value, that is, once a value is output, changes within the module do not affect that value. You have to write it as a function to get the internal value.
// lib.js var counter = 3; function incCounter() { counter++; } module.exports = { counter: counter, incCounter: incCounter, }; // main.js var mod = require('./lib'); console.log(mod.counter); // 3 mod.incCounter(); console.log(mod.counter); // lib. Js var counter = 3; function incCounter() { counter++; } module.exports = { get counter() { return counter }, incCounter: incCounter, }; $ node main.js 3 4Copy the code
ES6
A module is referenced dynamically and does not cache values. Variables in a module are bound to the module in which they reside.
// lib.js export let counter = 3; export function incCounter() { counter++; } // main.js import { counter, incCounter } from './lib'; console.log(counter); // 3 incCounter(); console.log(counter); / / 4Copy the code
ES6
The input module variable is just a “symbolic link”, so this variable is read-only and reassigning it will report an error.
// lib.js
export let obj = {};
// main.js
import { obj } from './lib';
obj.prop = 123; // OK
obj = {}; // TypeError
Copy the code
export
Through the interface, the output is the same value. Different scripts load the interface and get the same instance.
// mod.js
function C() {
this.sum = 0;
this.add = function () {
this.sum += 1;
};
this.show = function () {
console.log(this.sum);
};
}
export let c = new C();
Copy the code
- The script above
mod.js
The output is oneC
The instance. Different scripts load the module and get the same instance.
// x.js
import {c} from './mod';
c.add();
// y.js
import {c} from './mod';
c.show();
// main.js
import './x';
import './y';
Copy the code
- Now perform
main.js
And the output is1
.
$ babel-node main.js
1
Copy the code
- To prove the
x.js
andy.js
It’s all loadedC
The same instance of.
Node. Js loading
Node.js
requirementsES6
The module USES the.mjs
Suffix file name.Node.js
encounter.mjs
File, just think it isES6
Modules, strict mode is enabled by default and need not be specified at the top of every module file"use strict"
.
If you don’t want to change the suffix to.mjs, you can specify the type field as module in your project’s package.json file.
{
"type": "module"
}
Copy the code
-
You also need to use CommonJS modules, so you need to change the CommonJS script suffix to.cjs. If there is no type field, or if the type field is CommonJS, the.js script will be interpreted as a CommonJS module.
-
Summary:.mjs files are always loaded as ES6 modules,.cjs files are always loaded as CommonJS modules, and.js files are loaded depending on the setting of the type field in package.json.
-
Pay attention to,
ES6
Module andCommonJS
Try not to mix modules.require
Command cannot load.mjs
File, will report an error, onlyimport
The command can be loaded.mjs
File. In turn,.mjs
You can’t use it in a filerequire
Command is mandatoryImport.
-
ES6 modules and CommonJS support each other in node.js.
Cyclic loading
- “Cyclic loading” (
circular dependency
)Refers to,a
Script execution dependenciesb
The script,b
Script execution depends ona
The script. “Loop loading” indicates strong coupling and, if not handled well, can lead to recursive loading that makes the program unable to execute, so it should be avoided, but it can be difficult to avoid, especially on very complex projects.