JavaScript syntax
case sensitive
Everything is case-sensitive in JavaScript. Variables, functions, and operators are all case-sensitive.
For example: test and Test are two different variables
identifier
The so-called identifiers refer to the names of variables, functions, attributes, and function parameters.
The identifier can consist of one or more characters
The first character must be a letter, underscore, dollar sign
The rest Characters can include letters, underscores, dollar signs, and numbers
According to convention, identifiers generally use camel case, that is, the first letter of the first word is lowercase, and the first letter of each subsequent word is uppercase a>
Although this writing method is not mandatory, because this writing method is consistent with theJavaScript
built-in function and object naming method, so it is recommended
Example: firstSecond, myCar,
Comment
JavaScript adopts C language style when commenting code, including single-line and multi-line comments.
// 单行注释
/*
多行注释
*/
Comment shortcut keys:/+Ctrl
strict mode
Strict mode is a different JavaScript parsing and execution model. Non-standard writing will be processed in this mode, and errors will be thrown for unsafe activities. To enable strict mode for the entire script, you need to add
"use strict";
At the same time, strict mode can also specify a function to be executed in strict mode. Just put this preprocessing instruction at the beginning of the function body:
function doSomething() {
"use strict";
//函数体
}
statement
JavaScript
The statement ends with a semicolon, and the ellipsis means it is up to the parser to determine where the statement ends.
let sum = a + b //不推荐
let diff = a + b; //推荐
- Adding a semicolon helps prevent problems caused by omission;
- Problems caused by incomplete input content can be avoided;
- At the same time, adding a semicolon will also help delete empty lines of compression code;
- Also helps improve performance in some cases (the parser will add semicolons when and where)
Multiple statements can be combined into a single C-style code block. A code block starts with a left curly brace and ends with a right curly brace:
if(test) {
test = false;
console.log(test)
}
There must be code blocks when executing multiple statements, with a clear structure to prevent errors. (Best Practices)
// 有效 不推荐
if(test)
console.log(test)
// 推荐
if(test) {
console.log(test)
}
Keywords, reserved words
ECMA-262 stipulates that a number of keywords and future reserved words are reserved. These keywords have special uses.
// 关键字
break do in typeof
case else instanceof var
catch export new void
class extends return while
const finally super with
continue for switch yield
debugger function this
default if throw
delete import try
// 未来保留字---这些虽然还不是关键字但是未来可能会成关键字所以不推荐使用成标识符
// 始终保留
enum
// 严格模式下保留
implements package public
interface protected static
let provate
// 模块代码中保留
await
variable
The definition of variables in
JavaScript
is loose, meaning that variables can hold any type of data. Each variable is nothing more than a named placeholder used to hold an arbitrary value.ES
All versions can be usedvar
,ES6
can be used in the futurelet
,const
was
var message
This code defines a variablemessage
, which can be used to save any type of value. If not initialized, the variable will save a special valueundefined
var message = "hi"
This code defines a variablemessage
, and at the same time initializes and assigns a value to the variable. Variables can be saved and changed here.
var declaration scope
Variables defined using the var operator will become local variables that contain other functions.
function test(){
var message = "hi"; // 局部变量
}
test();
console.log(message); // 出错!
On the contrary, if the operator is not used, a global variable will be created.
function test(){
message = "hi"; // 局部变量
}
test();
console.log(message); // "hi"
It is worth noting that defining a global variable locally in a function will be difficult to maintain and cause trouble. Because I don’t know if the var was omitted intentionally.
When defining multiple variables using var
, you can use commas to separate each variable and optional initialization in one statement:
var message = "hi",
found = false,
age = 29;
// 这里的定义只是为了方便阅读
var statement hoisting
function foo(){
console.log(age);
var age = 26;
}
foo(); // undefined
The function here does not report an error because the JavaScript runtime equates the above code to the following code:
function foo(){
var age
console.log(age);
age = 26;
}
foo(); // undefined
This is the so-called variable promotion, that is, all变量声明提升到函数作用域顶部
are returned at the same time. There is no problem in using var to declare the same variable multiple times (值得注意的是变量提升的是变量,不是变量的值
)
function foo(){
var age = 16;
var age = 26;
var age = 36;
console.log(age);
}
foo(); // 36
at the same time,全局下声明的变量会成为Windows的属性
- declare scope
- Statement promotion
- Used globally
var
will become a property of the top-level objectwindows
let
var操作符
Compared with , have similar functions. The obvious differences are: var
and , let
let declares block scope
if (true) { let age = 26; console.log(age); // 26 } console.log(age); // ReferenceError:age 没有定义
var declares function scope
if (true) { var name = "Matt"; console.log(name); // Matt } console.log(name); // Matt
Here
age
The reason why the variable cannot be referenced outside the if block is because its scope is limited to the inside of the block.块作用域是函数作用域的子集
, so the scope restriction ofvar
also applies tolet
let
Redundant declarations within the same block scope are also not allowed. This will also result in an error:
var age;
var age;
let name;
let name; // SyntaxError; 标识符name已经声明过了
No error will be reported for nested identifiers because there are no duplicate declarations in the same block:
var name = "Nicholas";
console.log(name); // "Nicoholas"
if(true){
var name = "Matt";
console.log(name); // "Matt"
}
let age = 30;
console.log(age); // 30
if(){
let age = 16;
console.log(age); // 16
}
These two keywords do not declare variables of different types, they just point out that变量在相关作用域如何存在
the temporary dead zone
let
the variables declared will no longer promoted in scope. The moment of execution before let
is declared is called "暂时性死区
". Any reference to any variable declared later at this stage will throwReferenceError
// name会被提升
console.log(name); // undefined
var name = "Matt";
// age 不会被提升
console.log(age); // ReferenceError :age
var age = 16;
Global declaration
Variables declared using let
will not become attributes of the windows object globally, var
will
var name = "Matt";
console.log(window.name); // "Matt"
let age = 26;
console.log(window.age); // undefined
Conditional statement
When using var
, since the statement will be promoted, JS
the engine will automatically Statement在作用域的顶部合并成一个声明
. Because let的作用域是块
, it will not check whether the let statement has been used previously, and it is impossible to declare it without a statement.
cannot be solved using the
try/catch
statement or thetypeof
operator, because the scope oflet声明
in the conditional block is limited to the block.
The let statement in the for loop
before let
, the variables defined in the for
loop will penetrate outside the loop body , and using let
solves this problem.
for(var i = 0 ; i < 5; ++i){
//循环逻辑
}
console.log(i); // 5
for(let i = 0 ; i < 5; ++i){
//循环逻辑
}
console.log(i); // ReferenceError :i 没有定义
for(var i = 0 ; i < 5; ++i){
setTimeout(()=>console.log(i),0)
}
console.log(i); // 5,5,5,5,5
for(let i = 0 ; i < 5; ++i){
setTimeout(()=>console.log(i),0)
}
console.log(i); // 0,1,2,3,4
A common problem when using var
to declare variables is the strange declaration and modification of iteration variables. When using let
to declare iteration variables, JS引擎在后台会为每一个迭代循环声明一个新的迭代变量。每个setTimeout引用的都是不同的变量实例
.
const
const
The behavior of is basically the same as that of let
. The only important difference is that when using it to declare a variable, you must initialize the variable and try to modify the variable declared by const
will result in a runtime error
const age = 26;
age = 36; // TypeError:给常量赋值
// const 也不允许重复声明
const name = "Matt";
const name = "Nicholas"; // SyntaxError
// const 声明的作用域也是块
const name = "Matt";
if(){
const name = "Nicholas";
}
console.log(name); // Matt
The difference between var, let and const
var: variable declaration promotion, scope promotion,
let: temporary dead zone, block-level scope, no initialization,
const: The statement must be initialized at the same time, and an error will be reported if modified.
JavaScript data types
InJavaScript
there is a basic type of dataUndefined、Null、Boolean、Number、String、Symbol、Bigint
and a reference data typeObject
Data type detection
Because
JS
's type system is loose, a means is needed to determine the data type of any variable
typeof
typeof
For primitive types, the correct type can be displayed except null
typeof
For objects, except for functions, the correct type can be displayedobject
, so < /span>typeof
cannot accurately determine the type of a variable, so if you want to determine the correct type of an object, you can consider usinginstanceof
console.log(typeof 2); // number
console.log(typeof true); // boolean
console.log(typeof 'str'); // string
console.log(typeof []); // object []数组的数据类型在 typeof 中被解释为 object
console.log(typeof function(){
}); // function
console.log(typeof {
}); // object
console.log(typeof undefined); // undefined
console.log(typeof null); // object null 的数据类型被 typeof 解释为 object
instanceof
instanceof
can correctly determine the type of the object, because the internal mechanism is to determine whether the prototype of the type can be found in the prototype chain of the object
instanceof
can accurately determine the complex reference data type, but It cannot correctly determine the basic data type;
andtypeof
also have drawbacks. Although it can determine the basic data type (exceptnull
), However, among the reference data types, except for thefunction
type, other types cannot be judged
console.log(2 instanceof Number); // false
console.log(true instanceof Boolean); // false
console.log('str' instanceof String); // false
console.log([] instanceof Array); // true
console.log(function(){
} instanceof Function); // true
console.log({
} instanceof Object); // true
// console.log(undefined instanceof Undefined);
// console.log(null instanceof Null);
// 我们也可以试着实现一下 instanceof
function _instanceof(left, right) {
// 由于instance要检测的是某对象,需要有一个前置判断条件
//基本数据类型直接返回false
if(typeof left !== 'object' || left === null) return false;
// 获得类型的原型
let prototype = right.prototype
// 获得对象的原型
left = left.__proto__
// 判断对象的类型是否等于类型的原型
while (true) {
if (left === null)
return false
if (prototype === left)
return true
left = left.__proto__
}
}
console.log('test', _instanceof(null, Array)) // false
console.log('test', _instanceof([], Array)) // true
console.log('test', _instanceof('', Array)) // false
console.log('test', _instanceof({
}, Object)) // true
constructor
console.log((2).constructor === Number); // true
console.log((true).constructor === Boolean); // true
console.log(('str').constructor === String); // true
console.log(([]).constructor === Array); // true
console.log((function() {
}).constructor === Function); // true
console.log(({
}).constructor === Object); // true
//如果我创建一个对象,更改它的原型,constructor就会变得不可靠了
function Fn(){
};
Fn.prototype=new Array();
var f=new Fn();
console.log(f.constructor===Fn); // false
console.log(f.constructor===Array); // true
Object.prototype.toString.call()
toString() is the prototype method of Object. Calling this method can uniformly return a string in the format of "[object Xxx]", where Xxx is the type of the object. For Object objects, calling toString() directly will return [object Object]; for other objects, you need to call it to return the correct type information.
Object.prototype.toString({
}) // "[object Object]"
Object.prototype.toString.call({
}) // 同上结果,加上call也ok
Object.prototype.toString.call(1) // "[object Number]"
Object.prototype.toString.call('1') // "[object String]"
Object.prototype.toString.call(true) // "[object Boolean]"
Object.prototype.toString.call(function(){
}) // "[object Function]"
Object.prototype.toString.call(null) //"[object Null]"
Object.prototype.toString.call(undefined) //"[object Undefined]"
Object.prototype.toString.call(/123/g) //"[object RegExp]"
Object.prototype.toString.call(new Date()) //"[object Date]"
Object.prototype.toString.call([]) //"[object Array]"
Object.prototype.toString.call(document) //"[object HTMLDocument]"
Object.prototype.toString.call(window) //"[object Window]"
// 从上面这段代码可以看出,Object.prototype.toString.call() 可以很好地判断引用类型,甚至可以把 document 和 window 都区分开来。
// 全局下判断数据类型
function getType(obj){
let type = typeof obj;
// 先进行typeof判断,如果是基础数据类型,直接返回
if (type !== "object") {
return type;
}
// 对于typeof返回结果是object的,再进行如下的判断,正则返回结果
return Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/, '$1');
// 注意正则中间有个空格
}
// 代码验证,需要注意大小写,哪些是typeof判断,哪些是toString判断?
getType([]) // "Array" typeof []是object,因此toString返回
getType('123') // "string" typeof 直接返回
getType(window) // "Window" toString返回
getType(null) // "Null"首字母大写,typeof null是object,需toString来判断
getType(undefined) // "undefined" typeof 直接返回
getType() // "undefined" typeof 直接返回
getType(function(){
}) // "function" typeof能判断,因此首字母小写
getType(/123/g) //"RegExp" toString返回
Undefined
There is only one value in data type Undefined
undefined
.
Use
var
let
to define a variable but not initialized, then the value of this variable isundefined
var age; let name; console.log(age == undefined); // true console.log(name == undefined); // true
Note: Never explicitly set a variable to undefined.
undefined值主要用于比较,这个值的目的是为了正式明确空对象指针和未初始化变量的区别
Uninitialized and undefined variables use
typeof
to determine that the returned values are allundefined
, so we should do it immediately when defining variables Initialization, so that when a variable returnsundefined
, we can quickly know这个变量是未声明而不是声明了但是没有初始化
.let message; if(message){ //这块不会执行 } if(!message){ //这块会执行 } if(age){ // 这块会报错 }
Null
There is also only one value in data type Null
null
.
Logically speaking,
null
value represents a null pointer object, which is alsotypeof
passed inThe reason whynull
will returnobject
let car = null; console.log(typeof car); // object
undefined
The value is derived from unll
, so undefined
is superficially equal to unll
. But the purposes of the two are different. There is no need to explicitly set a variable value to undefined
for any variable, but if you don’t know what content to fill in a variable , can be filled with null
, which can maintain the semantics of null object pointer and further distinguish it from undefined
Boolean
Among the data typesBoolean
is one of the most frequently used typesJavaScript
and it has two valuestrue
and false
.
Regarding Boolean
we should know the conversion rules between different types and Boolean values:
type of data | Convert to true value | Convert to false value |
---|---|---|
Boolean | true | false |
String | non-empty string | " " (empty string) |
Number | Non-zero values (including infinity) | 0、NaN |
Object | any object | null |
Undefined | N/A (does not exist) | undefined |
The reason why you need to understand the content of these conversions is becauseconversions from other types to Boolean types are automatically performed in control flow statements.
let message = "hello world!";
if(message){
console.log("value is true");
}
// 这里可以看到message是字符串,但是console.log()会输出 "value is true" 。
// 因为这里message会自动的转换为等价的 true
Number
Regarding the Number
data type, first determine how it is written. According to the base system Number
can be written as follows:
// 最基本的数值字面量格式是十进制,直接写出来就可以
// 十进制。(不用前缀)
let num = 55; // 整数
// 二进制。(前缀0b 或 0B ,逢二进一)
let num21 = 0b10; // 2
let num22 = 0b100; // 4
// 八进制。(前缀 0 ,逢八进一 )
let num31 = 070; // 56
let num32 = 010; // 56
// 十六进制。(前缀 0x 或 0X ,逢十六进一)
let num41 = 0xA; // 10
let num42 = 0x1f; // 31
注意:在严格模式下八进制是无效的,会导致JavaScript引擎抛出错误。同时八进制字面量第一个数字必须是0,然后是相应的八进制数字(0-7).如果字面量中包含的数字超过有效的范围,后面的序列就会成为十进制。
除此之外,使用八进制和十六进制格式创建的数值在所有的数学操作中都被视为十进制
let num1 = 070; // 56
let num2 = 079; // 79 9超过八进制的取值,所以num2以及下面的num3成10进制
let num3 = 08; // 8
To be continued. . .