The cause of

Live on an especially greatly do before the speech, which answers the front of the book is worth reading, one of them is the Effective JavaScript, then start reading, to read and understand itself, record contents essential parts as well as the content layout, facilitate their review in the future learning and everybody to learn.

Due to the large number of contents, it is divided into each chapter to write the article, and the number of articles in each chapter is different, so each learning notes article shall be subject to the chapter.

Suitable for fragmented reading, compact reading friends. Try to let the little friends finish the series === 85+% of the whole book.

preface

Content overview

  • In the first chapter, beginners can get familiar with JavaScript and understand primitive type, implicit cast, encoding type and other concepts in JavaScript.
  • Chapter 2 focuses on JavaScript variable scope advice, not only explaining how to do it, but also explaining the reasons behind it to help readers understand it better.
  • Chapters 3 and 4 cover functions, objects, and stereotypes, which are at the heart of what sets JavaScript apart from other languages.
  • In chapter 5, the author introduces two common types, array and dictionary, which are easy to be confused, and gives some suggestions to avoid falling into some traps.
  • Chapter 6 covers library and API design;
  • Chapter 7 covers parallel programming, which is a necessary step toward becoming a JavaScript expert

JavaScript and ECMAScript

Clarify JavaScript and ECMAScript terminology. As you know, when people talk about ECMAScript, they usually mean the “ideal language” written by the INTERNATIONAL Standardization Organization, Ecma.

The name JavaScript means everything from the language itself, such as a vendor-specific JavaScript engine, DOM, BOM, and so on.

For clarity and consistency in this book, I will only use ECMAScript to talk about official standards, otherwise I will use JavaScript to refer to the language.

On Web

It’s hard to talk about JavaScript without talking about the Web, but this book is about JavaScript, not Web programming, so it focuses on the syntax, semantics, and pragmatics of the JavaScript language, not the apis and technologies of the Web platform.

About concurrent

One of the novel aspects of JavaScript is that its behavior is completely ambiguous in a concurrent environment. So, this is just some unofficial JavaScript features from a technical point of view, but in reality, all the major JavaScript engines share a common concurrency model.

Future versions of the ECMAScript standard may formalize the shared aspects of these JavaScript concurrency models

Chapter 1: “Get Used to JavaScript”

The JavaScript language is so approachable because it provides so few core concepts, but mastering the language requires more time and a deeper understanding of its semantics, features, and most effective idioms.

Each chapter covers a different topic for effective JavaScript programming. Chapter 1 covers some of the most basic topics

# 1: Know what version of JavaScript you’re using

Version of the problem

Due to JavaScript’s long history and implementation diversity, it is difficult to determine which features are available on which platforms. Web browsers, on the other hand, do not allow programmers to specify a version of JavaScript to execute code, and end users may use different versions of different Web browsers.

For example, the application works well on its own computer or test environment, but does not work when deployed to a different production environment. For example, the const keyword works fine when tested on JavaScript engines that support nonstandard features, but will show syntax errors when deployed to Web browsers that do not recognize the const keyword, and so on.

Strict mode

ES5 introduces another version control consideration — strict mode. This feature allows you to choose to disable some of the more problematic or error-prone features of the JavaScript language in restricted versions of JavaScript. The way to enable strict mode in a program is to add a specific string literal “Use strict” at the beginning of the program

The “Use strict” directive only works at the top of a script or function. If you use multiple separate files in development, one in strict mode and the other in non-strict mode, you need to connect them to a single file when deploying to production.

// file1.js
"use strict"
function f() {
  // ...
}

// file2.js
function g() {
  var grauments = []
}
Copy the code
  • If you start with file1.js, the connected code runs in strict mode

    // file1.js
    "use strict"
    function f() {
      / /...
    }
    // file2.js
    function g() {
      var arguments = []	// error: redefinition of arguments
    }
    Copy the code
  • If you start with file2.js, the connected code runs in non-strict mode

    // file2.js
    function g() {
      var arguments= []}// file1.js
    "use strict"
    function f() {
      // ...
    }
    Copy the code

Two schemes

You can stick to the “strict mode” or “non-strict mode” strategy in your own projects, but if you want to write robust code that deals with a wide variety of code links, there are two options.

  • The first solution is not to concatenate files that are rigorously checked with files that are not rigorously checked.

    • Is the simplest solution.
    • Limits your ability to control the file structure of your application or library.
    • Even in the best case, deploy at least two separate files. One contains files for strict schema checking and the other contains all files that do not need strict schema checking.
  • The second solution is to concatenate multiple files by wrapping themselves in a function expression that is invoked immediately. (Article 13 takes a deeper look at immediately called function expressions.)

    • Wrapping the contents of each file in a function that is called immediately, even in different modes, will be handled independently, as shown in the following example:

      // in the function expression called immediately
      (function () {
        // file1.js
        "use strict";
        function f() {
          // ...
        }
        // ...}) () (function () {
        // file2.js
        function g() {
          var arguments= []}}) ()Copy the code
    • Because the contents of each file are placed in a separate scope, the strict mode directive only affects the contents of this file.

    • However, this approach results in the contents of these files not being interpreted in the global scope.

conclusion

Therefore, in order to achieve more universal compatibility, to better pave the way for future new versions of Javascript, and eliminate some of the code running insecure, to ensure the safety of the code operation and so on. It is recommended to write code in strict mode when necessary

  • Decide which versions of JavaScript your application supports.
  • Make sure that any JavaScript features you use are supported for all the environments in which your application will run.
  • Always test strict code in an environment where strict schema checking is performed.
  • Beware of sequential scripts that have different expectations under different rigor modes.

# 2: Understand JavaScript floating point numbers

Floating point Numbers

JavaScript has only one Number type, Number.

typeof 17;	// "number"
typeof 98.6;	// "number"
typeof -2.1;	// "number"
Copy the code

In fact, all numbers in JavaScript are double-precision floating-point numbers, which perfectly represent integers up to 53 bits (which is how JavaScript implicitly converts to integers). Thus, despite the lack of an obvious integer type in JavaScript, integer arithmetic is perfectly possible.

0.1 * 1.9		/ / 0.19
-99 + 100 	/ / 1
21 - 12.3		/ / 8.7
2.5 / 5			/ / 0.5
21 % 8			/ / 5
Copy the code

Bitwise arithmetic operators

When performing bitwise arithmetic operators, JavaScript does not directly evaluate the operand as a floating-point number. Instead, it implicitly converts the operand to a 32-bit integer.

8 | 1		/ / 9
Copy the code

The actual steps performed by the above expression are

  1. JavaScript converts the digits 8 and 1 of a double-precision floating-point number to32An integer.
    1. The integer 8 represents a 32-bit binary sequence: 00000000 00000000 00000000 00001000, which can also be used(8).toString(2) // "1000"Method to view
    2. The integer 1 represents a 32-bit binary sequence: 00000000 00000000 00000000 00000001
  2. Use the integer bit pattern for bitwise arithmetic operator operations
    1. That is, a bitwise or operational expression combining two sequences of bits yields: 00000000 00000000 00000000 00001001
  3. Finally, the result is converted to a standard JavaScript floating point number.

Numbers in JavaScript are stored as floating-point numbers, which must be converted to integers and then back to floating-point numbers. However, there are cases where arithmetic expressions and even variables can only be evaluated using integers, and optimization compilers can sometimes infer these cases by internally storing numbers as integer geese to avoid redundant conversions.

The problem

A double-precision floating-point number can only represent a finite set of numbers, and when a series of operations are performed, the results become less and less accurate as rounding errors accumulate.

For example, real numbers are associative, which means that for any real numbers x, y, and z, it always follows that (x+y)+z = x+(y+z). For floating point numbers, however, this is not always the case:

(0.1 + 0.2) + 0.3	/ / 0.6000000 000000001
0.1 + (0.2 + 0.3)	/ / 0.6
Copy the code

To solve

  • An effective solution is to use integer values whenever possible so that there is no rounding error.
    • But be careful with JavaScript that all of your calculations only work53 ~ 2-2 ^ ^ 53

Personal solutions

  • The floating point number is simulated as a string, using the string to carry out the actual operation process.
  • Convert the decimal to a whole number before calculating
    • To a string
    • Using the split (.). Split string
    • Find the maximum index baseNum based on the number of decimals
    • And then you get the result(num1 * baseNum + NUM2 * baseNum)/baseNum;

conclusion

  • JavaScript numbers are double precision floating point numbers.
  • Integers in JavaScript are just a subset of double precision floating point numbers, not a separate data type.
  • Bitwise operators treat numbers as 32-bit signed integers.
  • Beware of precision traps in floating-point arithmetic

Rule 3: Beware of implicit casts

JavaScript implicit cast

JavaScript is surprisingly tolerant of type errors, and statically typed languages have expressions with different types of operations 3 + true; Is not allowed to run. JavaScript, on the other hand, produces result 4 without a hitch.

There are also rare cases in JavaScript where providing the wrong type will result in an immediate error.

// Call a non-function object
"hello"(1)	// error: not a function

// Attempts to select the null attribute
null.x;	// error: cannot rend property 'x' of null
Copy the code

Arithmetic operator

The arithmetic operators -, *, /, and % all attempt to convert their arguments to numbers before being evaluated. Operator + overrides both numeric addition and string concatenation.

2 + 3;	/ / 5
"hello" + "world";	// "hello world"
Copy the code

Since the addition operation is associative from the left (that is, the left associative law), the following equation follows.

1 + 2 + "3"		/ / "33"
/ / equal to
(1 + 2) + "3"	/ / "33"


1 + "2" + 3		/ / "123"
/ / equal to
(1 + "2") + 3	/ / "123"
Copy the code

A computing method of

Bitwise operators not only convert operands to numbers, but also to 32-bit integers.

  • Arithmetic operators:~,&,^|
  • Shift operator:<<>>>>><<<

These casts are convenient. For example, strings from user input, text files, or network streams are automatically converted.

"17" * 3;	/ / 51
"8" | "1";	/ / 9
Copy the code

NaN

Casts also hide errors. Variables that result in null do not fail in an arithmetic operation, but are implicitly converted to 0.

An undefined variable will be converted to a special floating-point value NaN, and instead of immediately throwing an exception, these casts continue, often with unpredictable results. Testing NaN values is also extremely difficult for two reasons

  1. JavaScript follows the vexing requirement of the IEEE floating-point standard that NaN is not equal to itself

    const x = NaN
    x === NaN		// false
    Copy the code
  2. The standard library function isNaN is also not very reliable.

    • With its own implicit cast, parameters are converted to numbers before being tested.
    isNaN(NaN)		// true
    isNaN("foo")	// true
    isNaN(undefined)	// true
    isNaN({})			// true
    isNaN({ valueOd: "foo" })	// true
    Copy the code

Fortunately, there is a simple and reliable idiom to test NaN

function isReallyNaN(x) {
	returnx ! == x }Copy the code

object

An object is converted to a string by implicitly calling its own toString method.

Match.toString()	// "[object Math]"
JSON.toString()	// "[object JSON]"
Copy the code

Similarly, objects can be converted to numbers through their valueOf methods. Its methods can be used to control the type conversion of objects.

"J" + { toString: function() { return "S"}}// JS

2 * { valueOf: function() { return 3}}/ / 6
Copy the code

When an object contains both toString and valueOf methods, it is not obvious which method the operator + should call. Therefore, JavaScript resolves this ambiguity by blindly selecting the valueOf method instead of the toString method.

const obj = {
  toString: function() {
    return "[object MyObject]"
  },
  valueOf: function() {
    return 17}}"object:" + obj		// "object: 17"
Copy the code

Thus, the overloaded operator + always behaves identically – a string or numeric representation of the same number – whether it is a concatenation or addition of objects.

In general, casting strings is far more common and useful than casting numbers. It is best to avoid using the valueOf method unless the object really is a number abstraction and obj.toString() can produce a string representation of obj.valueof ().

True value calculation

If to true value operation, | | and && operator need Boolean logic as operating parameters, but can take any value on time.

There are seven false values in JavaScript: false, 0, -0, NaN, “”, null, and undefined, and all other values are true.

A more rigorous way to check whether the parameter is undefined is to use typeof

function point(x, y) {
  if (typeof x === "undefined") {
    x = 320
  }
  if (typeof y === "undefined") {
    y = 240
  }
  return {x: x, y: y}
}

// This method compares 0 with undefind
point()		// {x: 320, y: 240}
point(0.0)		// {x: 0, y: 0}
Copy the code

If (x === undefined) {if (x == undefined) {… }

conclusion

  • Type errors can be hidden by implicit casts.
  • Overloaded operators+ Whether to add or concatenate depends on the parameter type.
  • Object throughvalueOfMethod should be implementedtoStringMethod, returns avalueOfMethod to generate a string representation of the number.
  • Tests whether a value is undefined and should be usedtypeofOr withundefinedCompare prices instead of using real calculations.

Rule 4: Primitive types are superior to encapsulated objects

Encapsulated object

The JavaScript standard library provides constructors to encapsulate the type of the original value. For example, you can create a String object that encapsulates a String value.

const s = new String("hello")
// You can also concatenate it with another value to create a string
s + "world"		// "hello world"
Copy the code

But unlike a raw String, a String object is a real object

typeof "hello"		// "string"
typeof s					// "object"
Copy the code

This means that you cannot use the built-in operators to compare the contents of two distinct strings; each String is a separate object, always equal to itself, regardless of content consistency.

const s1 = new String("hello")
const s2 = new String("hello")

s1 == s2		// false
s1 === s2		// false
Copy the code

Because the original value is not an object, you cannot set properties on the original value, but you can set properties on the encapsulated object.

const sObj = new String("hello")
const s = "hello"
sObj.prop = "world"
s.prop = "world"

sObj.prop		// "world"
s.prop		// undefined
Copy the code

role

The raison d ‘etre of encapsulated objects is that they are useful methods on constructors.

When we extract properties from raw values or make method calls, JavaScript implicitly converts them to the corresponding object type wrapper. For example, if the prototype object of String has a toUpperCase method that converts a String toUpperCase, you can call this method on the original String.

"hello".toUpperCase()		// "HELLO"
Copy the code

Each implicit wrapper creates a new String, and updating the first wrapper has no lasting effect.

This also often leads to errors in setting attributes to a raw value, which the program defaults to, leading to errors that are hard to find and difficult to diagnose.

conclusion

  • When compared for equality, the encapsulated object of the primitive type behaves differently from its original value.
  • Getting and setting properties of primitive type values implicitly creates encapsulated objects.

Rule 5: Avoid using the == operator for mixed types

The = = operator

Let’s look at an example. What do you think the result will be?

1.0 "e0"= = {valueOf: function() { return true}}Copy the code

Like the implicit cast described in article 3, they are all converted to numbers before comparison. The final result is equivalent to 1 == 1

  • The string “1.0e0” is resolved to 1
  • Anonymous objects also get the result true by calling their own valueOd method, which is then converted to a number to get 1

Therefore, it is easy to get some work done with these casts. For example, read a field from a Web form and compare it to a number

const today = new Date(a)if (form.month.value == (today.getMonth() + 1) && form.day.value == today.getDate()) {
  // ...
}

// is equivalent to the following implicit conversion to a number
const today = new Date(a)if (+form.month.value == (today.getMonth() + 1) && +form.day.value == today.getDate()) {
  // ...
}
Copy the code

Distinct from the === operator

When two attributes are of the same type, the == and === operators behave identically. But it’s better to use strict equality operators to accurately compare the content and type of data, rather than just the content of the data.

Transformation rules

The rules for the == operator cast are not obvious, but they have symmetry.

Conversion rules usually try to produce numbers, but they can become elusive when dealing with objects. Attempts to convert an object to its original value are determined by calling the valueOf and toString methods of the object. It is noteworthy that the Date object attempts to call both methods in reverse order.

As we mentioned in article 3, JavaScript by default calls valueOf and then toString to convert to the original value

Parameter Type 1 Parameter Type 2 Casts.
null undefined Always return true without conversion
Null or undefined Any other type other than null or undefined Always return false without conversion
Primitive type: String, number, Boolean, or Symbol The Date object Converts a primitive type to a number; Convert a Date object to a primitive type (toString method first, toString method second)
Primitive type: String, number, Boolean, or Symbol The Date object Converts a primitive type to a number; Convert non-date objects to primitive types (try valueOf method first, toString method second)
Primitive type: String, number, Boolean, or Symbol Primitive type: String, number, or Boolean Converts the primitive type to a number

conclusion

  • The == operator applies an obscure set of implicit cast rules when parameter types are different.
  • Use the === operator so that the reader can understand your comparison without involving any implicit casts.
  • When comparing different types of values, use your own display cast to make the program’s behavior clearer.

Rule 6: Understand the limitations of semicolon insertion

Semicolon insertion

Automatic semicolon insertion in JavaScript is a program parsing technique. The ability to infer omitted semicolons in some context and then effectively “insert” semicolons automatically into your program. The ECMAScript standard also specifies a semicolon mechanism so that optional semicolons can be portable between different JavaScript engines.

Semicolon insertion has its pitfalls when parsing, and JavaScript syntax has additional restrictions on it. So take the pain out of removing unnecessary semicolons by learning the three rules for semicolon insertion.

Rule Number one

Semicolons are inserted only before the} tag, after one or more line breaks, and at the end of program input.

That is, you can only omit a semicolon at the end of a code block, line, or segment of a program, not in consecutive statements.

legal

function area(r) { r = +r; return Math.PI * r * r }
Copy the code

illegal

function area(r) { r = +r return Match.PI * r * r }	// error
Copy the code

Rule Number two

Semicolons are inserted only if subsequent input tokens cannot be parsed.

In other words, semicolon insertion is an error-correcting mechanism. We always look to the beginning of the next statement to see if we can legally omit the semicolon.

Five character problem

There are five explicitly problematic characters to watch out for: (, [, +, -, and /. These are context-dependent and can all be used as an expression operator or a prefix to a previous statement.

  • (a)

    a = b
    (f());
    / / equivalent to the
    a = b(f());
    
    // Will be parsed into two separate statements
    a = b
    f()
    Copy the code
  • []

    a = b
    ["r"."g"."b"].forEach(function (key) {
      background[key] = foreground[key] / 2;
    })
    / / equivalent to the
    a = b["r"."g"."b"].forEach(function (key) {
      background[key] = foreground[key] / 2;
    })
    
    // Will be resolved into two separate statements, one assignment and one array forEach method
    a = b
    ["r"."g"."b"].forEach(function (key) {
      background[key] = foreground[key] / 2;
    })
    Copy the code
  • + and –

    a = b
    +c;
    / / equivalent to the
    a = b + c;
    
    // Will be parsed into two separate statements, one to assign and one to a positive integer.
    a = b
    +c
    
    / / - as above
    Copy the code
  • / : Start character with special meaning for regular expression markup

    a = b
    /Error/ i.test(str) && fail();
    / / equivalent to the
    a = b / Error / i.test(str) && fail();	// '/' will be parsed as a division operator
    
    // Will be parsed into two separate statements
    a = b
    /Error/ i.test(str) && fail()
    
    Copy the code

Script connection problem

Omitting the semicolon can cause script wiring problems if each file may consist of a large number of function call expressions. When each file is loaded as a separate program, semicolons are automatically inserted at the end, turning the function call into a statement.

// file1.js
(function() {
  // ...}) ()// file2.js
(function() {
  // ...}) ()Copy the code

But when we use multiple files as program loading files, if we omit the semicolon, the result will be parsed into a single statement.

(function() {
  // ...}) () (function() {
  // ...}) ()Copy the code

We can defensively prefix each file with an extra semicolon to protect the script from careless joins. That is, if the initial statement of the file begins with all five character problems, do the following.

// file1.js; (function() {
  // ...}) ()// file2.js; (function() {
  // ...}) ()Copy the code

In summary, omiting a semicolon from a statement is not only a matter of looking out for the next tag in the current file (character issues), but also for any tag that may occur after the statement after the script is joined.

JavaScript syntax restricts production

JavaScript syntactically restricts production ** to not allowing a newline between two characters, forcing the insertion of a semicolon. ** Examples are as follows:

return{};// Will be parsed into three separate statements.
return; {}; ;Copy the code

In other words, a newline after the return keyword forces the automatic insertion of a semicolon, and the code example is parsed as a return statement with no arguments, followed by an empty code block and an empty statement.

In addition to the syntactically restricted generation of return, there are other JavaScript statements that restrict production.

  • throwstatements
  • Having a display labelbreakcontinuestatements
  • Post-increment or decrement operator

Rule Number three

Semicolons are not automatically inserted as separators in the head of the empty for statement or in the while of the empty body of the loop.

This means you need to include a semicolon explicitly in the header of the for loop.

// Replacing a semicolon with a newline in the header of the for loop will result in a parsing error.
for (let i = 0, total = 1	// parse error
     i < n
   	 i++) {
  total *= 1
}
Copy the code

The while loop inside the empty body also needs to display a semicolon.

function infiniteLoop() { while (true)}// parse error
function infiniteLoop() { while (true); }	/ / right
Copy the code

conclusion

  • Semicolons are inserted only before the} tag, after one or more line breaks, and at the end of program input.
  • Semicolons derive semicolons only if the following token cannot be parsed.
  • In order to(,[,+,-/Never omit a semicolon before a statement beginning with a character.
  • When scripts are connected, explicitly insert semicolons between scripts.
  • inreturn,throw,break,continue,++--Ground arguments cannot be preceded by line breaks.
  • A semicolon cannot be derived as a header for a for loop or as a separator for an empty statement.

Rule 7: Treat a string as a sequence of 16-bit code units

Unicode concept

The Unicode concept is that every character unit in the world’s writing systems is assigned a unique integer between 0 and 1114 111, known in Unicode terminology as a code point.

Unicode is hardly any different from other character encodings (for example, ASCII). The difference, however, is that ASCII maps each index to a unique binary representation, and Unicode allows multiple code points with different binary encodings. Different encodings trade off between the number of strings stored and the speed of operation (i.e., time versus space). There are several Unicode encoding standards, the most popular of which are UTF-8, UTF-16, and UTF-32.

Code units

Unicode designers miscalculated the size range of code points based on historical data. Originally, ucS-2 was the original standard for 16-bit code, that is, Unicode had 2^16 code points. Since each code point can hold a 16-bit number, when a code point is mapped one-to-one to its encoding element, it is called a code unit.

The result was 16-bit encoded strings on many platforms at the time. Java, for example, and JavaScript is not far behind, so each element of a JavaScript string is a 16-bit value.

expand

Unicode has now expanded its original scope as well, extending the standard from 2^16 at the time to more than 2^20 code points, with the additional scope organized into 17 word ranges of 2^16 code points in size. The first subscope, called the basic multilingual plane, contains the initial 2^16 code points, and the remaining 16 scopes are called the auxiliary plane.

! [image-20210621102240846](/Users/Mr-luo/Library/Application Support/typora-user-images/image-20210621102240846.png)

JavaScript code unit

Ucs-2 becomes obsolete as the range of code points expands, so UTF-16 uses proxy pairs to represent additional code points, a pair of 16-bit code units that collectively encode a code point equal to or greater than 2^16.

For example, the musical symbol 𝄞 assigned to the treble clef has a code point U+1D11E (the preferred hexadecimal notation for Unicode at code point 119 070), which UTF-16 decodes by combining the bits selected by two code units 0xD834 and 0xDdle.

"𝄞".charCodeAt(0);		// 56606 (0xD834)
"𝄞".charCodeAt(1);		// 56606 (0xDD1e)

'\ud834\udd1e'		/ / "𝄞"
Copy the code

JavaScript has adopted 16-bit string elements, and string attributes and methods such as Length, charAt, and charCodeAt are based on the code unit level rather than the code point level. So simply put, an element of a JavaScript string is a 16-bit unit of code.

! [image-20210621124352078](/Users/Mr-luo/Library/Application Support/typora-user-images/image-20210621124352078.png)

JavaScript engines can internally optimize the storage of string content, but given string properties and methods, strings behave like sequences of UTF-16 code units.

That is, although 𝄞 actually has only one code point, because it is based on the code unit level,.length is shown as the number of code units 2.

"𝄞".length		/ / 2
"a".length	/ / 1
Copy the code

Methods that extract a character from the string yield code units, not code points.

"𝄞".charCodeAt(0);		// 56606 (0xD834)
"𝄞".charCodeAt(1);		// 56606 (0xDD1e)

"𝄞".charAt(1) = = =""		// false indicates that the second code unit is not a null character
"𝄞".charAt(2) = = =""		// true

'\ud834\udd1e'		/ / "𝄞"
Copy the code

Regular expressions also work at the code unit level because of the single-character pattern. Match a single code unit.

/^.$/.test("𝄞");		// false
/ ^.. $/.test("𝄞")		// true
Copy the code

conclusion

This means that applications cannot rely on string methods, length values, index lookups, or many regular expression patterns if they need to manipulate code points. If you want to use code points other than BMP, it’s a good idea to turn to libraries that support code points.

Although JavaScript’s built-in string data types work at the code unit level, that doesn’t stop some apis from being aware of code points and proxy pairs. For example, URI operator functions: sendcodeURI, decodeURI, encodeURIComponent and decodeURIComponent.

So every time a JavaScript environment provides a library to manipulate strings (such as manipulating the content of a Web page or performing I/O operations on strings), you need to consult those library documentation to see how they handle the full range of Unicode code points.

  • Understand Unicode concepts.
  • Understand code points and code units.
  • JavaScript strings consist of 16-bit code units rather than Unicode code points.
  • JavaScript uses two code units to represent Unicode code points 2^16 and above. These two code units are called proxy pairs.
  • The agent pair dropped offString element count.length,charAt,charCodeAtMethods and regular expression patterns (for example.) have been affected.
  • Write string operations that recognize code points using third-party libraries.
  • Whenever you use a library with string operations, you need to consult the library documentation to see how it handles the entire range of code points.

After the speech

The above is the first chapter of the content of learning 1~7 rules, focusing on familiar with JavaScript, understand JavaScript primitive type, implicit cast, encoding type and other concepts;

The series are as follows:

  • Effective JS ’68 Rules: One to Seven
  • Effective JS’s 68 Rules 8 to 17
  • Effective JS’s 68 Rules: 18 to 29
  • Effective JS’s 68 Rules 30 to 42
  • 68 Rules of Effective JS: 43 to 52
  • Effective JS’s 68 rules: 53 to 60
  • 68 Rules of Effective JS: 61 to 68

If there is no link, you are learning…