Syntax and data types in the basis of JavaScript language

Language foundation

Mainly based on ECMAScript version 6

grammar

  1. The case sensitive variable test and the variable test are two different variables.

  2. The names of identifier variables, functions, attributes or function parameters follow the hump case, that is, the first letter of the first word is lowercase, and the first letter of each subsequent word is uppercase

  3. Notes single line notes and block notes

  4. Strict mode is a different JavaScript parsing and execution model. Nonstandard writing will be handled in this mode. If it is unsafe to throw an error, this "use strict" enables strict mode to be placed in the whole or method

  5. Statements are recommended to end with a semicolon

  6. Keywords and reserved words it is better not to use keywords and reserved words as identifiers and attribute names to ensure compatibility with past and future ECMAScript versions. Keywords: break do in typeof case else instanceof var catch export new void class extensions return while const finally super with continue for switch yield debugger function this default if throw de Let import try reserved word: enum implements package public interface protected static let private
    await

  7. Variables are used to hold any type of data var, const, and let
    var: you can change not only the saved value, but also the type of the value (the default value is undefined without initialization). In strict mode, variables named eval and arguments cannot be defined, otherwise syntax errors will occur. The scope declared by var is the function scope. Variables will be automatically promoted to the top of the function scope.
    Let: you can change not only the saved value, but also the type of the value. The scope of the let declaration is the block scope, and the let does not allow redundant declarations in the same block scope. It is used for for loops, if judgments, etc. for unilateral block area activities and does not affect other functions
    Const: you can change not only the saved value, but also the type of the value (the default value is undefined without initialization). When you declare a variable with const, you must initialize the variable at the same time, and trying to modify the variable declared by const will lead to a runtime error. It is only applicable to the reference of the variable it points to.

  8. Recommended declaration style: do not use var, const takes precedence, let takes second place. Ideal practice: use const to declare variables first, and then let.

data type

Data type: Undefined, Null, Boolean, Number, String, Symbol, Object

  1. Type of operator to determine the data type of any variable
     "undefined" indicates that the value is undefined;
     "boolean" indicates that the value is boolean;
     "string" indicates that the value is a string;
     "number" indicates that the value is a numerical value;
     "object" means that the value is an object (not a function) or null;  "function" means that the value is a function;
     "symbol" indicates that the value is a symbol.
  2. When an undefined type declares a variable with var or let but is not initialized, it is equivalent to giving an undefined value to the variable
  3. Null type null value represents a null object pointer. When defining variables to save object values in the future, it is recommended to initialize with null instead of other values.
  4. Boolean type Boolean literal values true and false are case sensitive. True is not equal to 1 and false is not equal to 0
  5. Number type indicates integer and floating-point values. Maximum value: Infinity minimum value: with - infinity, NaN: indicates that the operation to return a value fails. Dividing 0, + 0 or  0 will return NaN. Value conversion: Number(), parseInt() and parseFloat()
    Number() Use: when Boolean value is used, true is converted to 1 and false to 0. When numeric value is used, it is returned directly. When null, it is returned to 0. When undefined, it is returned to NaN. When numeric character is preceded by plus and minus signs, it is converted to a decimal value, valid floating-point value is converted to corresponding floating-point value, valid hexadecimal value is converted to decimal integer, and empty string is returned to 0 , NaN is returned in case of the above exception. The object calls the valueOf() method and then number (). If the result is NaN, the toString() method is called, and then the string is converted according to the rules of string conversion
    parseInt() use: only focus on whether the string has a numeric mode. Spaces in front of the string are ignored directly, starting from the first non space. If the first character is not a numeric value, the result returns NaN. If the first character is a numeric value, the plus and minus signs are used to detect each character in turn until the end of the string (if the string is marked with "0x") The beginning will be interpreted as hexadecimal integer (direct to decimal), parseInt ("10", 10) is parsed in decimal
    Use of parseFloat(): the principle is basically the same as that of parseInt(). The difference is that it can recognize all floating-point formats discussed earlier and decimal formats (the first zero is always ignored). It only parses decimal values, and hexadecimal values always return 0
  6. String type: represents zero or more sequences of 16 bit Unicode characters. Strings can be marked with double quotation marks ("), single quotation marks ('), or back quotation marks (`)
    toString() use: if there is a value, return the result. If the value is null, return "null". If the value is undefined, return "undefined".
    String.raw use: directly obtain the literal content of the original template instead of the converted character representation
  7. Symbol type: ensure that object attributes use unique identifiers and there is no risk of attribute conflict.
    Symbol() use: you can pass in a string parameter as the description of the symbol. You can debug the code through this string in the future. The symbol() function cannot be used as a constructor together with the new keyword
    Symbol.for() use: performs idempotent operations on each string key.
    Symbol.keyFor() uses: to query the global registry
    Symbol can be used as an attribute in object, and symbol can be used with @ @. For example, @ @ iterator refers to Symbol.iterator.
    Symbol.asynciiterator use: this symbol represents the function that implements the asynchronous iterator API. Promise instances are returned successively through its next() method. It can be returned by explicitly calling the next() method or implicitly through the asynchronous generator function.
class Emitter { 
 constructor(max) { 
 this.max = max; 
 this.asyncIdx = 0; 
 } 
 async *[Symbol.asyncIterator]() { 
 while(this.asyncIdx < this.max) { 
 yield new Promise((resolve) => resolve(this.asyncIdx++)); 
 } 
 } 
} 
async function asyncCount() { 
 let emitter = new Emitter(5); 
 for await(const x of emitter) { 
 console.log(x); 
 } 
} 
asyncCount(); 
// 0 
// 1 
// 2 
// 3 
// 4

Symbol.hasInstance uses: a method that determines whether a constructor object recognizes an object as its instance. Since the instanceof operator will look for this attribute definition on the prototype chain, it is the same as looking for other attributes on the prototype chain

class Bar {} 
class Baz extends Bar { 
 static [Symbol.hasInstance]() { 
 return false; 
 } 
} 
let b = new Baz(); 
console.log(Bar[Symbol.hasInstance](b)); // true 
console.log(b instanceof Bar); // true 
console.log(Baz[Symbol.hasInstance](b)); // false 
console.log(b instanceof Baz); // false

Symbol.isconcapspreable: a Boolean value. If true, it means that the object should level its array elements with Array.prototype.concat(). Example

let initial = ['foo']; 
let array = ['bar']; 
console.log(array[Symbol.isConcatSpreadable]); // undefined 
console.log(initial.concat(array)); // ['foo', 'bar'] 
array[Symbol.isConcatSpreadable] = false; 
console.log(initial.concat(array)); // ['foo', Array(1)]
let arrayLikeObject = { length: 1, 0: 'baz' }; 
console.log(arrayLikeObject[Symbol.isConcatSpreadable]); // undefined 
console.log(initial.concat(arrayLikeObject)); // ['foo', {...}] 
arrayLikeObject[Symbol.isConcatSpreadable] = true; 
console.log(initial.concat(arrayLikeObject)); // ['foo', 'baz'] 
let otherObject = new Set().add('qux'); 
console.log(otherObject[Symbol.isConcatSpreadable]); // undefined 
console.log(initial.concat(otherObject)); // ['foo', Set(1)] 
otherObject[Symbol.isConcatSpreadable] = true; 
console.log(initial.concat(otherObject)); // ['foo']

Symbol.iterator uses: functions that implement the iterator API.

class Emitter { 
 constructor(max) { 
 this.max = max; 
 this.idx = 0; 
 } 
 *[Symbol.iterator]() { 
 while(this.idx < this.max) { 
 yield this.idx++; 
 } 
 } 
} 
function count() { 
 let emitter = new Emitter(5); 
 for (const x of emitter) { 
 console.log(x); 
 } 
} 
count(); 
// 0
// 1 
// 2 
// 3 
// 4

Symbol.match uses: regular expressions to match strings

class FooMatcher { 
 static [Symbol.match](target) { 
 return target.includes('foo'); 
 } 
} 
console.log('foobar'.match(FooMatcher)); // true 
console.log('barbaz'.match(FooMatcher)); // false 
class StringMatcher { 
 constructor(str) { 
 this.str = str; 
 } 
 [Symbol.match](target) { 
 return target.includes(this.str); 
 } 
} 
console.log('foobar'.match(new StringMatcher('foo'))); // true 
console.log('barbaz'.match(new StringMatcher('qux'))); // false

Symbol.replace use: replace the matching substring in a string

class FooReplacer { 
 static [Symbol.replace](target, replacement) { 
 return target.split('foo').join(replacement); 
 } 
} 
console.log('barfoobaz'.replace(FooReplacer, 'qux')); 
// "barquxbaz" 
class StringReplacer { 
 constructor(str) { 
 this.str = str; 
 } 
 [Symbol.replace](target, replacement) { 
 return target.split(this.str).join(replacement); 
 } 
} 
console.log('barfoobaz'.replace(new StringReplacer('foo'), 'qux')); 
// "barquxbaz"

Symbol.search use: returns the index in the string that matches the regular expression

class FooSearcher { 
 static [Symbol.search](target) { 
 return target.indexOf('foo'); 
 }
 console.log('foobar'.search(FooSearcher)); // 0 
console.log('barfoo'.search(FooSearcher)); // 3 
console.log('barbaz'.search(FooSearcher)); // -1 
class StringSearcher { 
 constructor(str) { 
 this.str = str; 
 } 
 [Symbol.search](target) { 
 return target.indexOf(this.str); 
 } 
} 
console.log('foobar'.search(new StringSearcher('foo'))); // 0 
console.log('barfoo'.search(new StringSearcher('foo'))); // 3 
console.log('barbaz'.search(new StringSearcher('qux'))); // -1

Symbol.species use: constructor to create derived objects

class Bar extends Array {} 
class Baz extends Array { 
 static get [Symbol.species]() { 
 return Array; 
 } 
} 
let bar = new Bar(); 
console.log(bar instanceof Array); // true 
console.log(bar instanceof Bar); // true 
bar = bar.concat('bar'); 
console.log(bar instanceof Array); // true 
console.log(bar instanceof Bar); // true 
let baz = new Baz(); 
console.log(baz instanceof Array); // true 
console.log(baz instanceof Baz); // true 
baz = baz.concat('baz'); 
console.log(baz instanceof Array); // true 
console.log(baz instanceof Baz); // false

Symbol.split uses the: method to split the string at the index that matches the regular expression.

class FooSplitter { 
 static [Symbol.split](target) { 
 return target.split('foo'); 
 } 
} 
console.log('barfoobaz'.split(FooSplitter)); 
// ["bar", "baz"] 
class StringSplitter { 
 constructor(str) { 
 this.str = str; 
 } 
 [Symbol.split](target) { 
 return target.split(this.str); 
 } 
} 
console.log('barfoobaz'.split(new StringSplitter('foo'))); 
// ["bar", "baz"]

Symbol.toPrimitive use: convert the object to the corresponding original value. Many built-in operations attempt to force an object to a raw value, including strings, values, and unspecified raw types. For example, defining a function on the Symbol.toPrimitive property of an instance can change the default behavior.

class Foo {} 
let foo = new Foo(); 
console.log(3 + foo); // "3[object Object]" 
console.log(3 - foo); // NaN 
console.log(String(foo)); // "[object Object]" 
class Bar { 
 constructor() { 
 this[Symbol.toPrimitive] = function(hint) { 
 switch (hint) { 
 case 'number': 
 return 3; 
 case 'string': 
 return 'string bar'; 
 case 'default': 
 default: 
 return 'default bar'; 
 } 
 } 
 } 
}
let bar = new Bar(); 
console.log(3 + bar); // "3default bar" 
console.log(3 - bar); // 0 
console.log(String(bar)); // "string bar"

Personal understanding: why is the result of 3 + bar "3default bar" bar? It is uncertain to convert it to number and string. If you add bar to Number()

console.log(3+ Number(bar)); // 6
console.log(3+ String(bar)); // "3string bar"

Symbol.toStringTag use: creates the default string description of the Object. When obtaining the Object ID through the toString() method, the instance identifier specified by Symbol.toStringTag will be retrieved. The default is "Object".

let s = new Set(); 
console.log(s); // Object {  } 
console.log(s.toString()); // "[object Set]"
console.log(s[Symbol.toStringTag]); // "Set"
class Foo {} 
let foo = new Foo(); 
console.log(foo); // Object {  } 
console.log(foo.toString()); // [object Object] 
console.log(foo[Symbol.toStringTag]); // undefined 
class Bar { 
 constructor() { 
 this[Symbol.toStringTag] = 'zzz'; 
 } 
} 
let bar = new Bar(); 
console.log(bar); // Object {  }
console.log(bar.toString()); // "[object zzz]"
console.log(bar[Symbol.toStringTag]); // "zzz"

Symbol.unscopables use: all and inherited properties of an object will be excluded from the with environment binding of the associated object

let o = { foo: 'bar' }; 
with (o) { 
 console.log(foo); // bar 
} 
o[Symbol.unscopables] = { 
 foo: true 
}; 
with (o) { 
 console.log(foo); // ReferenceError 
}
  1. Object type: an object is actually a collection of data and functions. Object is followed by the name of the object type through the new operator
    To create. let o = new Object(); Recommended let o = new object; Not recommended. Each object instance has the following properties and methods.
    constructor: the function used to create the current object.
    hasOwnProperty(propertyName): used to judge whether a given property exists on the current object instance (not the prototype)
    Sex. The property name to check must be a string (such as o.hasOwnProperty("name") or a symbol.
    isPrototypeOf(object): used to judge whether the current object is the prototype of another object.
    propertyIsEnumerable(propertyName): used to judge whether a given property can be used. Like hasOwnProperty(), the property name must be a string.
    toLocaleString(): returns the string representation of the object, which reflects the localized execution environment of the object.
    toString(): returns the string representation of the object.
    valueOf(): returns the string, numeric value or Boolean representation corresponding to the object. It is usually the same as the return value of toString().

Tags: Javascript Front-end

Posted on Fri, 03 Dec 2021 19:51:15 -0500 by coja1