Types and syntax

type

Built-in types

  • null
  • undefined
  • boolean
  • number
  • string
  • object
  • symbol
typeof undefined === "undefined"; // true typeof true === "boolean"; // true typeof 42 === "number"; // true typeof "42" === "string"; // true typeof { life: 42 } === "object"; Typeof function a () {} === "function" // true typeof [1, 2, Typeof Symbol() === "Symbol "; typeof Symbol() ===" Symbol "; // null Special typeof NULL === "object" // trueCopy the code

Values and types

Variables have no type, and operations on variables with Typeof are operations on the values that the variable holds.

undefined&undeclared

Undefined is a type of value and undeclared means variables are not declared yet.

var a
a // undefined
b //  Uncaught ReferenceError: b is not defined

typeof a // undefined
typeof b // undefined
Copy the code

Typeof defense mechanism

In particular, multiple script files share global namespace load variables

  • Judge undeclared variables

    // Uncaught ReferenceError: DEBUG is not defined if (DEBUG) {console.log("DEBUG is starting")}Copy the code
    • typeof
    if (typeof DEBUG ! == "undefined") { console.log("DEBUG is starting") }Copy the code
    • window
     if (window.DEBUG) {
         console.log("DEBUG is starting")
     }
    Copy the code

value

An array of

tips

  • Delete deletes an array but does not change the length
  • Create a “sparse array” (an array of blank or vacant cells) with undefined different from that of display assignments
  • Arrays are numerically indexed, and indexes are also objects, so they can contain string keys and attributes. If a string key can be cast to a decimal array, it is treated as a numeric index.
var a = []
a[0] =1
a['footer'] = 2

console.log(a.length) // 1
console.log(a['footer']) // 2
console.log(a.footer) // 2

a['13'] = 14 
console.log(a.length) // 14
Copy the code

An array of class

A set of values that can survive a numeric index such as a list of DOM elements returned by DOM query operations and function arguments accessed as a list via the arguments object

  • Class arrays are converted to arrays
function foo () {
    console.log(arguments) // {"0":"bar","1":"baz","2":"bam"}
    let arr = Array.prototype.slice.call(arguments)
    console.log(arr) // ["bar","baz","bam"]
}
let obj = {}
foo.apply(obj, ['bar','baz', 'bam'])
Copy the code
  • ES6 Array.from

string

Strings are sort of like arrays, with length, indexof, and concat. But strings in JS are immutable and arrays are mutable. So strings cannot “borrow” mutable member functions of arrays such as reverse

digital

The integer

An “integer” is a decimal number without a decimal

Console. log(42.0 === 42) // trueCopy the code

Number method

Var a = 42.59; a.toPrecision( 1 ); // "4e+1" a.toPrecision( 2 ); // "43" a.toPrecision( 3 ); // "42.6" a.torecision (4); // "42.59" a.torecision (5); // "42.590" a.torecision (6); // "42.5900" // invalid syntax: 42. ToFixed (3); // The following syntax is valid: (42).tofixed (3); // "42.000" 0.42. ToFixed (3); / / "0.420" 42.. toFixed( 3 ); / / "42.000"Copy the code

Supported formats

Binary, octal, hexadecimal

0xf3; // 243 hexadecimal 0Xf3; / / same as above 0 o363; // 243 octal 0O363; / / same as above 0 b11110011; // binary 0B11110011 for 243; / / same as aboveCopy the code

0.1 + 0.2 = = = 0.3

JS “machine precision” : 2^-52. In ES6 this value is defined in number. EPSILON and can be used to compare whether two numbers are equal.

function numberCloseToEqual (a, B) {return math.abs (a-b) < number.epsilon} let a = 0.1 + 0.2 let b = 0.3 console.log(numberCloseToEqual(a, B)) // true console.log(numberCloseToEqual(0.000000001, 0.000000000002)) // falseCopy the code

The safe range of integers

The Number rendering method determines that the security range of “integer” needs to be much smaller than number. Max_value(1.7976931348623157e+308). The largest integer that can be “safely” rendered is 2^53-1, defined in ES6 as macth.max_safe_INTEGER, corresponding to the smallest integer bit number.min_safe_INTEGER.

Integer detection

  • ES6 in Number. IsInteger ()

    Function print(val) {console.log(val)} print(number.isINTEGER (42)) // true print(number.isinteger (42.000)) // true Print (number.isINTEGER (42.3)) // falseCopy the code

    Implement number.isINTEGER () for versions prior to ES6

    if (! Number.isInteger) { Number.isInteger = function (number) { return typeof number === 'number' && number % 1 == 0 } }Copy the code
  • Check whether the value is a safe integer

Number.isSafeInteger(…) , one more safe value than Number. IsInteger

32 – bit signed integer

All bitwise operators work only with 32-bit numbers, so the safe range of numbers becomes math.pow (-2, 31) to math.pow (2, 31); Such as: |, &, < <, > > bitwise operators in detail

The special numerical

Not the value of the value

Undefined has only one value, that is, undefined. The NULL type also has only one value, null. Their names are both types and values.

Undefined and null are often used to refer to “empty” or “non-value” values. There are some subtle differences. Such as:

  • Null means an empty value.
  • Undefined means missing value.

Or:

  • Undefined means never assigned
  • Null means that a value has been assigned, but currently has no value

Null is a special keyword, not an identifier, and cannot be used and assigned as a variable. Undefined, however, is an identifier that can be used and assigned as a variable.

void

Void 0 is normally used to get undefined

Special digital

  • NaN can be understood as’ invalid value ‘, ‘failed value’. Typeof NaN === ‘number’ is true; NaN == NaN is false.

    • You can use global isNaN() to check for NaN, but in fact the check is not accurate. IsNaN () actually checks for parameters that are not NaN and are not numbers.
    window.isNaN(NaN) // true
    window.isNaN('foo') // true
    window.isNaN(2) // false
    Copy the code
    • ES6 can use number.isnan ()
    Number.isNaN(NaN) // true
    Number.isNaN('foo') // false
    Number.isNaN(2) // false
    Copy the code

    Built-in implementation

    if (! Number.isNaN) { Number.isNaN = function (n) { return n ! == n } }Copy the code
  • An infinite number of

Number.POSITIVE_INFINITY Number.NEGATIVE_INFINITY

console.log(1 / 0, -1 / 0) // Infinity,-Infinity
console.log(Infinity / Infinity) // NaN
Copy the code
  • Zero value

Simple scalar primitive type values (strings and numbers, etc.) are assigned/passed by value copy, while compound values (objects, etc.) are assigned/passed by reference copy. Unlike references/Pointers in other languages, references in JavaScript cannot point to other variables/references, only to values.

The primary function

  • Common native functions:

String() Number() Boolean() Array() Object() Function() RegExp() Date() Error() Symbol()

Log (a) // String {" ABC "} 0: "a" 1: "B" 2: "c" length: 3 __proto__: String [[PrimitiveValue]]: "abc" console.log(typeof a) // object console.log(a instanceof String) // true console.log(Object.prototype.toString.call(a)) // [object String]Copy the code

Internal attributes [[class]]

All the typeof return value as the object of “object” (arrays) contains an internal properties [[Class]], but this property cannot be accessed directly, usually by the object. The prototype. The toString () to look at it.

Object. The prototype. ToString. Call ([1, 2, 3]); // "[object Array]" Object.prototype.toString.call( /regex-literal/i ); // "[object RegExp]" Object.prototype.toString.call( null ); // "[object Null]" Object.prototype.toString.call( undefined ); // "[object Undefined]" Object.prototype.toString.call( "abc" ); // "[object String]" Object.prototype.toString.call( 42 ); // "[object Number]" Object.prototype.toString.call( true ); // "[object Boolean]"Copy the code

The value of the [[Class]] property inside the Array is Array, and the value of the regular expression is RegExp.

Although the Null() and Undefined() native constructors do not exist, the internal [[Class]] property values are still “Null” and “Undefined”.

Object wrapper

JS automatically wraps a wrapper object around a primitive type value

Encapsulate objects to resolve doubts

Console. log(new Boolean(false)) if (new Boolean(false)) {// Console. log(1)}Copy the code

opened

If you want to get the valueOf the primitive type in the encapsulated object, you can use the valueOf() function:

var a = new String( "abc" ); 
var b = new Number( 42 ); 
var c = new Boolean( true ); 
a.valueOf(); // "abc" 
b.valueOf(); // 42 
c.valueOf(); // true 
Copy the code

Implicit split (cast) :

var a = new String( "abc" ); var b = a + ""; // the value of b is "ABC" typeof a; // "object" typeof b; // "string"Copy the code

Cast casting

You can distinguish between casts that take place at compile time in statically typed languages and casts that take place at runtime in dynamically typed languages.

Abstract value operation

ToString

  • For ordinary objects, unless its own definition, the toString () (Object. The prototype. The toString () returns the value of [[Class]] internal attributes, such as “[Object Object]”. If an object has its own toString() method, that method is called and its return value is used when stringified.

  • The array call default toString() has been redefined toString all cells together with “,”, as in:

var a = [1, 2, 3]
console.log(a) // "1, 2, 3"
Copy the code

Tips: JSON stringing

  • Json.stringify () is the same as ToString
    • Json.stringify (..) for strings, numbers, Booleans, and null The rules are basically the same as ToString.
    • If passed to json.stringify (..) Is defined in the toJSON() method, which is called before stringification to convert the object to a safe JSON value.

All safe JSON values (json-safe) can be used with json.stringify (..) String literation. A safe JSON value is one that can be rendered in a valid JSON format.

  • Unsafe JSON value

Undefined, function, symbol (ES6+), and objects that contain circular references (objects that refer to each other in an infinite loop). JSON.stringify(..) Undefined, function, and symbol are automatically ignored when encountered in objects, and null is returned in arrays (to keep the unit position unchanged).

  • Object defines the toJSON method, which is first called when JSON is stringed and then serialized with its return value.

ToNumber

NaN is returned on failure and is treated as decimal for hexadecimal data.

Binary: 0B /0B; Octal: 0o/ 0o; Hexadecimal value: 0x/ 0x

var a = { valueOf: function(){ return "42"; }}; var b = { toString: function(){ return "42"; }}; Var = c (4, 2); c.toString = function(){ return this.join( "" ); / / "42"}; Number( a ); // 42 Number( b ); // 42 Number( c ); // 42 Number( "" ); // 0 Number( [] ); // 0 Number( [ "abc" ] ); // NaN let num = '0x123' console.log(Number(num)) // 291Copy the code

ToBoolean

  • False value
    • undefined
    • null
    • false
    • +0, -0, and NaN
    • ‘ ‘

ToPrimitive

In order to convert a value to the corresponding primitive type value, the abstract operation ToPrimitive (see ES5 specification Section 9.1) first checks (through the internal operation DefaultValue, see ES5 specification Section 8.12.8) if the value has a valueOf() method. If a primitive type value is present and returned, that value is used for the cast. If not, the return value of toString() is used (if present) for the cast.

If neither valueOf() nor toString() returns a base type value, TypeError is generated.

Displays casts

  • Number, a String,
  • toString
  • The unary operators +, –

Common operation

  • The date display is converted to numbers
    var timestamp = +new Date()
    
    var timestamp = new Date().getTime(); 
    // var timestamp = (new Date()).getTime(); 
    // var timestamp = (new Date).getTime();
    
    // Best Es5
    var timestamp = Date.now()
    Copy the code
  • The ~ operator

Binary operators, mentioned above, are one of them. When encountered, the value is first cast to a 32-bit number, and then the byte operation “not” is performed (flipping each character)

Delta X is roughly the same thing as minus X plus 1.

~42 // -(42+1) ===> -43
Copy the code

The return value of indexOf is set to -1. In C language, -1 is the “sentinel value, which is endowed with special significance. -1 represents failure in execution, and greater than -1 represents success. This convention is followed in JS.

Optimize indexOf judgment

let a = "Hello World"; console.log(~a.indexOf( "lo" )); // 4 <-- true! console.log(~a.indexOf( "ol" )); // 0 <-- false!Copy the code
  • Degree is amputated

~~ is the result of ToInt32 because it is reversed twice

~~ X truncates a value to a 32-bit integer

Displays parsed numeric strings

Parsing a numeric string allows non-numeric characters in the string, parsing from left to right, stopping if non-numeric characters are encountered. The conversion does not allow non-numeric characters, or it will fail and return NaN.

a = "42"
b = "42px"

console.log(Number(a), Number(b)) // 42 NaN
console.log(parseInt(a), parseInt(b)) // 42 42
Copy the code

parseInt(..) The parameter coercion is converted to a string before parsing

The parseInt (0.000008); // 0 ("0" from "0.000008") parseInt(0.0000008); // 8 ("8" comes from "8e-7") parseInt(false, 16); // 250 ("fa" from "false") parseInt(parseInt, 16); // 15 ("f" comes from "function.." ) parseInt( "0x10" ); // 16 parseInt( "103", 2 ); / / 2Copy the code

The display is converted to Boolean

Boolean (X) or!!!!! X

Privacy Type conversion

Tips

When an operand is an object, ToPrimitive is called first, followed by [[DefaultValue]], with numbers as the context, as explained in ToPrimitive.

The ToNumber abstract operation works similarly with objects. For example, if the valueOf() operation on an array fails to get a simple primitive value, toString() will be called instead.

Implicit cast between a string and a number

  • If one of the operands of the operator is a string or a string is available, string concatenation is performed; Otherwise, add numbers.

Implicitly cast a Boolean value

  • if (..) A conditional expression in a statement.
  • for ( .. ; . ; ..) The conditional expression in the statement (second).
  • while (..) And do.. while(..) A conditional judgment expression in a loop.
  • ? The conditional judgment expression in:.
  • Logical operators | | (logical or) and && (and logic) than the left operand (as conditions to break).

&& and | |

&& and | | is not really a “logical operators”, the exact closer and selector operator or operand selector operator. Because they don’t return booleans, the return value is one of two operands.

var a = 42; 
var b = "abc"; 
var c = null; 
console.log(a || b, a && b, c || b, c && b) // 42,abc,abc,null
Copy the code

For | |, if the condition judgment result to true will return to the first operand (a and c) values, if false is returned (b) the value of the second operand.

&&, on the other hand, returns the value of the second operand (b) if true or the value of the first operand (a and c) if false.

The cast of symbols

ES6 allows explicit casts from symbols to strings, however implicit casts produce errors.

Symbols cannot be cast to numbers (both explicit and implicit yield errors), but they can be cast to booleans (both explicit and implicit yield true).

= = = = =

Official explanation of equality judgment

“== allows casting in equality comparisons, whereas === does not.”

performance

Both === and == check the type of operands. If the type of == is different, the cast is performed. The performance difference is negligible in microseconds. In fact, when comparing two objects, they work the same way; When two objects point to the same value, they are considered equal and no cast is performed.

Equal to compare

  • Numbers and Strings

    a = 42
    b = "42"
    
    console.log(a === b) // false
    console.log(a == b) // true
    Copy the code
    • How do I convert a= b?

      ES5 specification

      • If a is a number and b is a string, return a == ToNumber(b)
      • If a is a string and b is a number, return ToNumber(a) = b
  • Other types and Boolean types

    b = "42"
    
    console.log(b == true) // false
    Copy the code

    ES5 specification

    • If a is Boolean, return ToNumber(a) == b
    • If b is Boolean, return a == ToNumber(b)
  • Null, and undefined

    Null and undefined are equal in == (they are also equal to themselves), except for other values.

    var a = null; 
    var b; 
    a == b; // true 
    a == null; // true 
    b == null; // true 
    a == false; // false 
    b == false; // false 
    a == ""; // false 
    b == ""; // false 
    a == 0; // false 
    b == 0; // false
    Copy the code
  • Objects and non-objects

    ES5 states that the == operator ToPrimitive (characters, arrays only) is performed on both sides of the object. Boolean types are first cast to numbers

a = 42
b = [42]

a == b // true

c = "obc"
d = Object(c)
c == d
Copy the code
  • other
    • Change the built-in native prototype

      Number.prototype.valueOf = function () {
        return 3
      }
      
      console.log(new Number(2) == 3) // true
      
      Copy the code
    • A == 2 && A == 3

      ValueOf = function () {return I ++} var a = new Nummber(2) if (a == 2 &&a == 3) {// true} // hijacking let obj = {a: 1} object.defineproperty (obj, 'a', {get () {i++}})Copy the code
    • Common == judgment

      "0" == null; // false "0" == undefined; // false "0" == false; // true -- no! "0" == NaN; // false "0" == 0; // true "0" == ""; // false false == null; // false false == undefined; // false false == NaN; // false false == 0; // true -- no! false == ""; // true -- no! false == []; // true -- no! false == {}; // false "" == null; // false "" == undefined; // false "" == NaN; // false "" == 0; // true -- no! "" = = []; // true -- no! "" = = {}; // false 0 == null; // false 0 == undefined; // false 0 == NaN; // false 0 == []; // true -- no!Copy the code
    • extreme

      2 == [2] // true [] == ! [] // true "" == [null] // true 0 == "\n" // trueCopy the code

Comparison of abstract relations

A <= b is treated as! B < a

  • Both sides of the comparison are strings: compare in alphabetical order
  • Others: ToPrimivite is called first, and if a non-string occurs, the ToNumber cast to a number is used for comparison

grammar

Statements and expressions

A statement is a complete sentence and consists of a set of words or N expressions connected by operators. Where expressions are equivalent to phrases, expressions can be made up of smaller expressions that have full meaning or none.

The result value of the statement

Each statement has a result value, which specifies that the result value defining var is undefined.

The syntax does not allow us to assign the result of a statement only to another variable, as in:

Var a, b a = if (true) {b = 4+38} // if code block outputs 42 on the console, but assignment to another variable is not allowedCopy the code

But in practice we can get results from statements in other ways: eval() is strongly deprecated, ES7’s do{… } expressions execute code blocks

Expression side effect

You can assign the result value of a statement to merge a judgment condition

Context rule

  • {… } This leads to a less cognitive feature of JS (not recommended), label statements
    foo: for(let i = 0; i < 4; I++) {// foo tag for (let j =0; j < 4; J ++) {if (I == j) {console.log(' skipped ', I, J) // skip to next loop I +1 continue foo} if ((I * j) % 2 == 1) {console.log(' skip odd ', I, j) // skip this loop, J +1 continue} console.log(' not skipped ', I, j)}}Copy the code

    Tagged loop jumps are even more useful when used with breaks to jump from inner to outer layers

    foo: for(let i = 0; i < 4; i++) { for (let j =0; j < 4; J ++) {if ((I * j) % 2 == 1) {console.log(' skip odd ', I, j) break foo} console.log(' skip odd ', I, j)}}Copy the code

Tips

[] + {} // "[object Object]"
{} + [] // 0
Copy the code

In the first line of code, {} appears in the + operator expression, so it is treated as a value (null object). Chapter 4 explained that [] will be cast to “” and {} will be cast to “[object object]”.

But in the second line, {} is treated as a separate, empty block of code (doing nothing). You don’t need a semicolon at the end of a block of code, so there’s no syntactic problem. Finally + [] explicitly casts [] (see Chapter 4) to 0.

Cold knowledge

  • There is no else if in JS, but if and else can omit the code block {} when they contain only a single statement.
if (a) {
} else {
    if (b) {} else {}
}
Copy the code

Operator priority

Operator priority official details

Asynchrony and Performance