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)
  • ES6 common but ignored methods (Module 9)
  • Common but ignored methods of ES6 (Development specification of the Tenth Bullet Project)
  • ES6 common but ignored method (eleventh bullet Decorator)

The latest proposal

  • ES6- Latest proposal

Do expression

  • indoexpressionThe proposalPreviously, block-level scope was a single statement that encapsulated multiple operations with no return value.doExpressions allow block-level scopes to become expressions, that is, to return values,Returns the value of the last internally executed expression.
Let x = do {let t = f(); t * t + 1; }; / / perform different functions in different Settings let x = do {the if (foo () ()} {f else if (bar ()) {g ()} else {h ()}};Copy the code

Throw expression

  • JavaScriptGrammar rulesthrowIs a command that throws an error and cannot be used in expressions.
Console. log(throw new Error());Copy the code
  • Now there is aThe proposal ,throwCan be used directly in expressions.
Function save(filename = throw new TypeError("Argument required")) {} lint(ast, {with: () => throw new Error("avoid using 'with' statements.") }); // let typeof x === number? x : throw new Error("Is NaN"); / / logical expression let val = value | | throw new Error (" Invalid value ");Copy the code
  • In grammar,throwThe throw inside the expression is no longer a command, but an operator. To avoid contact withthrowCommand confusion,provisionsthrowThe occurrence at the beginning of the line is interpreted asthrowStatement, instead ofthrowExpression.

Partial execution of a function

  • Multi-argument functions sometimes need to bind one or more of their arguments and then return a new function.
function add(x, y) { return x + y; } function add7(x) { return x + 7; } // bind const add7 = add.bind(null, 7); // arrow function const add7 = x => add(x, 7);Copy the code
  • Now we have oneThe proposal, making it easier to bind parameters and return a new function. This is called the partial execution of a function (partial application).?Is a placeholder for a single parameter,.Is a placeholder for multiple arguments.
f(x, ?) f(x, ...) f(? , x) f(... , x) f(? , x, ?) f(... , x, ...)Copy the code
  • ?and.Can only appear in a function call, and a new function is returned.
const g = f(? , 1,...). ; // const g = (x,... y) => f(x, 1, ... y);Copy the code
  • Partial execution of a function can also be used for methods of an object.
let obj = { f(x, y) { return x + y; }}; const g = obj.f(? , 3); g(1) // 4Copy the code
Pay attention to the point
  1. The partial execution of a function is based on the original function. If the original function changes, the new function generated by the partial execution will immediately reflect the change.
let f = (x, y) => x + y; const g = f(? , 3); g(1); F = (x, y) => x * y; g(1); / / 3Copy the code
  1. If the presupplied value is an expression, the expression is not evaluated at definition time, but at each invocation.
let a = 3; const f = (x, y) => x + y; const g = f(? , a); g(1); // change the value of a = 10; g(1); / / 11Copy the code
  1. If the new function has more arguments than the number of placeholders, the extra arguments are ignored.
const f = (x, ... y) => [x, ...y]; const g = f(? , 1); g(2, 3, 4); / / (2, 1)Copy the code
  1. .Will only be collected once if more than one partial execution of the function is used., then each.Will all have the same value.
const f = (... x) => x; const g = f(... , 9,...). ; g(1, 2, 3); // [1, 2, 3, 9, 1, 2, 3]Copy the code

Pipe operator

  • The proposal.JavaScriptThe pipe is an operator that writes|>. It has an expression on the left and a function on the right. The pipe operator passes the value of the expression on the left to the function on the right for evaluation.
X | > f / / equal to f (x)Copy the code
  • The pipe operator can pass only one value, which means that the function to its right must be a single-argument function. If it is a multi-argument function, it must be currified to the single-argument version.
function double (x) { return x + x; }
function add (x, y) { return x + y; }

let person = { score: 25 };
person.score
  |> double
  |> (_ => add(7, _))
// 57
Copy the code
  • The pipe operator forawaitDelta functions also apply.
X | > await f / / equivalent to await f (x) const userAge = userId | > await fetchUserById | > getAgeFromUser; // equivalent to const userAge = getAgeFromUser(await fetchUserById(userId));Copy the code

Numeric separator

  • In European and American languages, long numeric values allow a separator (usually a comma) to be added every three digits, increasing the readability of the value. For instance,1000You can write1000.
  • Now we have oneThe proposalTo allowJavaScriptUse an underscore (_) as a separator.
let budget = 1_000_000_000_000;
budget === 10 ** 12 // true
Copy the code
  • JavaScriptThe numeric delimiter does not specify the number of digits in the interval. Decimal and scientific notation can also use numeric delimiters.
123_00 === 12_300 // true 12345_00 === 123_4500 // true 12345_00 === 1_234_500 // true // decimal 0.000_001 // Scientific counting 1e10_000Copy the code
  • Pay attention to the point.
    1. Cannot precede the value (leading) or the last (trailing).
    2. Two or more delimiters cannot be joined together.
    3. There can be no separators before and after the decimal point.
    4. In scientific notation, representing exponentseorEThere can be no delimiters before and after.
    // All errors 3_.141 3._141 1_e12 1e_12 123__456 _1464301 1464301_Copy the code
  • In addition to decimal, other numeric values can also use separators.
// Binary 0b1010_0001_1000_0101 // hexadecimal 0xA0_B0_C0Copy the code
  • A delimiter cannot follow a hexadecimal prefix0b,0B,0o,0O,0x,0X.
// Error 0_b111111000 0b_111111000Copy the code
  • Number(),parseInt(),parseFloat()Three functions that convert strings to numeric values, with no numeric delimiters supported. The main reason is that the designers of the proposal believe that numerical separators are primarily for the convenience of writing numerical values when coding, rather than for processing external input data.
Number('123_456') // NaN
parseInt('123_456') // 123
Copy the code

Math.signbit()

  • Math.sign()Is used to determine whether a value is positive or negative, but if the parameter is0, it will return0. In real programming, one value is+ 0or0It’s very troublesome because they’re equal.
Math.sign(-0) // -0
+0 === -0 // true
Copy the code
  • There was a proposal that was introducedMath.signbit()Method to determine whether a number has a sign bit.
Math.signbit(2) //false
Math.signbit(-2) //true
Math.signbit(0) //false
Math.signbit(-0) //true
Copy the code
  • The algorithm of this method is as follows.
    1. If the parameter isNaNTo return tofalse.
    2. If the parameter is0To return totrue.
    3. If the argument is negative, returntrue.
    4. Other cases returnfalse.

Double colon operator

  • Arrow functions can be boundthisObject, greatly reducing explicit bindingthisObject writing (call,apply,bind), arrow functions are not suitable for all situations, so there is oneThe proposal, proposed “function binding” (function bind) operator used to replacecall,apply,bindThe call. The function binding operators are two colons side by side (: :), the double colon is an object on the left and a function on the right.
foo::bar; // Equivalent to bar.bind(foo); foo::bar(... arguments); // equivalent to bar.apply(foo, arguments);Copy the code
  • If the left side of the double colon is empty and the right side is a method of an object, it binds that method to that object.
var method = obj::obj.foo; Var method = :obj.foo; let log = ::console.log; // Var log = console.log.bind(console);Copy the code
  • If the result of the double colon operator is still an object, we can use the chain notation.
import { map, takeWhile, forEach } from "iterlib";

getPlayers()
::map(x => x.character())
::takeWhile(x => x.strength > 100)
::forEach(x => console.log(x));
Copy the code

Realm API

  • Realm API The proposalProvide sandbox functionality (sandboxTo allow code to be quarantined, preventing those quarantined from getting the global object. To provide aRealm()Constructor to generate aRealmObject. The object ofglobalProperty refers to a new top-level object similar to the original top-level object.RealmThe top-level object and the original top-level object are two different objects.
const globalOne = window; const globalTwo = new Realm().global; Let a1 = globalOne. Evaluate (' [1, 2, 3] '); Let a2 = globalTwo. Evaluate (' [1, 2, 3] '); a1.prototype === a2.prototype; // false a1 instanceof globalTwo.Array; // false a2 instanceof globalOne.Array; // falseCopy the code
  • RealmYou can only run inside the sandboxECMAScriptSyntactically providedAPICannot run those provided by the host environmentAPI.For example,consoleIt’s not a syntax standard, it’s provided by the host environment.
globalTwo.evaluate('console.log(1)') // throw an error: Console = globalone. console;Copy the code
  • Realm()The constructor can take a parameter object that has aintrinsicsAttributes can be specifiedRealmThe sandbox inherits the methods of the original top-level object.
const r1 = new Realm();
r1.global === this;
r1.global.JSON === JSON; // false

const r2 = new Realm({ intrinsics: 'inherit' });
r2.global === this; // false
r2.global.JSON === JSON; // true
Copy the code

#! The command

  • UnixAll command line scripts support #! Command, also known asShebangHashbang. This command, placed on the first line of the script, specifies the executor of the script.
// The first line of the Bash script. #! /bin/sh // The first line of the Python script. #! /usr/bin/env pythonCopy the code
  • Now we have oneThe proposalforJavaScriptScripts introduce#!Command, written in the first line of the script file or module file.
// Write the first line of the script file #! /usr/bin/env node 'use strict'; console.log(1); // Write on the first line of the module file #! /usr/bin/env node export {}; console.log(1);Copy the code
  • With this line of work,UnixThe script can be executed directly from the command line.
$node hello.js # hashbang $./hello.jsCopy the code
  • forJavaScriptFor the engine, it will#!Read it as a comment and ignore this line.

import.meta

  • When using a module, developers sometimes need to know something about the template itself (such as the path to the module). Now we have oneThe proposalforimportThe command adds a meta-attributeimport.metaReturns meta information about the current module.
  • import.metaCan only be used inside the module, if used outside the module will report an error.
  • This property returns an object whose various properties are meta information about the currently running script. The standard does not specify which attributes are included, and it is up to each operating environment to decide. In general,import.metaThere will be at least two properties.
  1. import.meta.url
  • import.meta.urlReturns the value of the current moduleURLThe path. For example, the path to the current module main file ishttps://foo.com/main.js.import.meta.urlI’m going to return this path. If there is also a data file in the moduledata.txtTo get the path to the data file, use the following code.
new URL('data.txt', import.meta.url)
Copy the code
  • Node.jsEnvironment,import.meta.urL always returns the local path, i.efile:URLProtocol string, for examplefile:///home/user/foo.js.
  1. import.meta.scriptElement
  • import.meta.scriptElementIs a browser-specific meta-property that returns the one that loaded the module<script>Element, equivalent todocument.currentScriptProperties.
// the HTML code is // <script type="module" SRC ="my-module.js" data-foo=" ABC "></script> // my-module.js internally executes the following code import.meta.scriptElement.dataset.foo // "abc"Copy the code

conclusion

  • In the latest proposal, there is a write feature that I think is very useful. For example,
    1. throwExpressions, which we can’t use in block-level scopes before, can be used to do some exception handling directly in expressions after the proposal is approved.
    2. Pipe operator (|>), we can use the pipe operator to write directly on a line when we call consecutively, and the logic is clearer.
    3. The double colon operator (: :), before we bindthisIn order to usecall,apply,bindOr you can use the arrow function, but in some cases the arrow function is limited, so the double colon operator can be written in shorthand and can handle special cases outside of the arrow function.
    4. Other features have their own uses, maybe we have not encountered some situations in the development, the existence is reasonable.
  • ES6(ES2016(collectively) more and more features, we need to continue to be familiar with the new special new, which is what we will use in the development, can improve our development efficiency, every time after reading there will be a different harvest, we can also go back at intervals to deepen the impression.
  • ES6This concludes the series of articles on common but overlooked methods: Scatter flowers 🎉🎉🎉, thank you for your support.