DOM、BOM、Window、Document#
DOM 是操作文档的 API,Document 是其一个对象。
BOM 是操作浏览器的 API,Window 是其一个对象。
function component(s) {
const element = document.createElement('div');
element.innerHTML = s;
return element;
}
document.body.appendChild(component("hello"));SSR vs CSR#
服务器渲染和客户端渲染。
ES5、ES6、ES2021#
两个等号与三个等号的区别#
严格相等:===,非严格相等:==。
使用
==时,如果两边的类型不一样,会先进行类型转换。===是直接进行比较,不会进行类型转换。
一般不推荐使用 == 了,几乎没有场景适用,比较 null 或 undefined 的话可以直接显式比较,用了 == 还会被人怀疑使用的正确性,增加阅读负担。但是大于等于和小于等于仍然是 >= 和 <=。
变量声明#
let#
let low = 0;
let low = 0, high = nums.length - 1;var 和 let#
var 在全局级别(函数外部)进行声明会自动变成 Window对象的一个属性:
var name = "John";
window.name === name // true
let 或者 const 则不会:
let name = "John";
window.name === name // false
var 存在变量提升现象:闭包或函数内部重新声明后会对外部相同变量进行覆盖。
const#
解构赋值#
解构赋值语法是一种 Javascript 表达式。通过解构赋值可以将 属性/值 从 对象/数组 中取出,赋值给其他变量。
function main() {
l = [1, 2, 3];
let [a, b, ...rest] = l;
d = { hello: "world", foo: "bar", other: "other" };
let { hello, foo, ...other } = d;
console.log(a);
console.log(b);
console.log(rest);
console.log(hello);
console.log(foo);
console.log(other);
}
/*
1
2
[ 3 ]
world
bar
{ other: 'other' }
*/注意通过 map 的 set() 方法赋值的不能进行解构,会得到 undefined。
正则表达式#
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions
var re = /ab+c/;
// 等价于
var re = new RegExp("ab+c");循环控制#
JS 支持传统的 for 语法,此外还有以下 for 的用法
for … of#
for (const element of ['a', 'b', 'c']) {
console.log(element);
}for … in#
for...in 是为遍历对象属性而构建的,不建议与数组一起使用,数组可以用 for...of
for...in 得到的是属性名称。
var obj = {a:1, b:2, c:3};
for (var prop in obj) {
console.log("obj." + prop + " = " + obj[prop]);
}
// Output:
// "obj.a = 1"
// "obj.b = 2"
// "obj.c = 3"
do…while#
function main(params) {
let i = 0
do {
console.log(i)
i += 1
} while (i < 10);
}statement 执行至少一次,并在每次 condition 值为真时重新执行。
while#
程序控制#
条件判断#
需要注意数组越界的问题,不会报错,只会返回 undefined,然后 if 得到的结果就永远是 false。
a = [1]
if(1 < a[-1]) {
console.log("1 < a[-1]");
} else {
console.log("1 > a[-1]");
}
// 1 > a[-1]
console.log(1 < a[-1]);
console.log(1 > a[-1]);
// false
// false
with#
严格模式下不允许使用 with 语句,否则将视为语法错误(所以能看懂就行了,尽量别用。。)
var obj = {
host: "https://yindongliang.com",
url: "posts",
};
with (obj) {
host = "https://github.com";
url = "repos";
a = "global";
}
console.log(host); // undefined
console.log(url); // undefined
console.log(a); // global
注意:当 with 的 obj 没有某个属性却在作用域里重新声明的时候,该属性会被泄露到全局变量里。
switch#
这里有坑:省略 break 关键字会执行下一个 case
switch (expression) {
case value: statement
break;
case value: statement
break;
case value: statement
break;
default:
...try…throw…catch…finally#
function myFunction() {
var message, x;
message = document.getElementById("p01");
message.innerHTML = "";
x = document.getElementById("demo").value;
try {
if(x == "") throw "值是空的";
if(isNaN(x)) throw "值不是一个数字";
x = Number(x);
if(x > 10) throw "太大";
if(x < 5) throw "太小";
}
catch(err) {
message.innerHTML = "错误: " + err + ".";
}
finally {
document.getElementById("demo").value = "";
}
}关键字#
void 运算符#
void 运算符 对给定的表达式进行求值,然后返回 undefined。
void (async function () {
console.log('hello void')
})();typeof#
typeof 的对象一般是对象。
instanceof#
instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
扩展运算符 ...#
运算符 ~~#
~~ 将数据转化为 Number 类型
~~3.141592654 // 3
delete#
用于删除对象的某个属性。
const Employee = {
firstname: 'John',
lastname: 'Doe'
};
console.log(Employee.firstname);// expected output: "John"
delete Employee.firstname;
console.log(Employee.firstname);// expected output: undefined
函数#
普通函数#
function showMessage() {
alert( 'Hello everyone!' );
}
showMessage(); // 函数调用
匿名函数#
function main(params) {
params = {hello: "world"}
return function f() {
console.log("hello", params)
}
}箭头函数#
在 js 中区分函数的引用和函数的执行,箭头函数返回的是函数的引用,而不是函数的执行结果。
箭头函数中 this 指的是外部的 this,因为箭头函数没有 this,匿名函数则是内部的 this。
- 箭头函数没有 this
- 箭头函数没有 arguments 变量
- 不能用 new
- 不能用 super
生成器函数#
调用一个生成器函数并不会马上执行它里面的语句,而是返回一个这个生成器的 迭代器 ( iterator )对象。当这个迭代器的 next() 方法被首次(后续)调用时,其内的语句会执行到第一个(后续)出现 yield 的位置为止,yield 后紧跟迭代器要返回的值。或者如果用的是 yield*(多了个星号),则表示将执行权移交给另一个生成器函数(当前生成器暂停执行)。
严格模式#
- 针对整个脚本文件
在脚本文件的第一行添加
"use strict";- 针对单个函数
将"use strict"放在函数体的第一行,则整个函数以"严格模式"运行。
function strict(){
"use strict";
return "这是严格模式。";
}- 将整个脚本文件放在一个立即执行的匿名函数之中。
(function (){
"use strict";
// some code here
})();类(class)#
ES6 引入了面向对象的概念(class)
static
extends
getter 和 setter#
get 语法将对象属性绑定到查询该属性时将被调用的函数。
const obj = {
log: ['a', 'b', 'c'],
get latest() {
if (this.log.length === 0) {
return undefined;
}
return this.log[this.log.length - 1];
},
set latest(value) {
console.log(value)
}
};
console.log(obj.latest);
// expected output: "c"
obj.latest = 1
// expected output: 1
constructor#
Symbol#
如果我们要在对象字面量 {...} 中使用 symbol,则需要使用方括号把它括起来。
let id = Symbol("id");
let user = {
name: "John",
[id]: 123 // 而不是 "id":123
};这是因为我们需要变量 id 的值作为键,而不是字符串 “id”。
https://zh.javascript.info/symbol#dui-xiang-zi-mian-liang-zhong-de-symbol
this 作用域#
Promise,async/await#
let promise = new Promise(function(resolve, reject) {
// executor(生产者代码)
});Promise#
由 new Promise 构造器返回的 promise 对象具有以下内部属性:
state— 最初是"pending",然后在resolve被调用时变为"fulfilled",或者在reject被调用时变为"rejected"。result— 最初是undefined,然后在resolve(value)被调用时变为value,或者在reject(error)被调用时变为error。
与最初的 “pending” promise 相反,一个 resolved 或 rejected 的 promise 都会被称为 “settled”。
then/catch/finally
async/await#
async function f() {
return 1;
}在函数前面的 “async” 这个单词表达了一个简单的事情:即这个函数总是返回一个 promise。其他值将自动被包装在一个 resolved 的 promise 中。
await 只在 async 函数内工作。await 实际上会暂停函数的执行,直到 promise 状态变为 settled,然后以 promise 的结果继续执行。这个行为不会耗费任何 CPU 资源,因为 JavaScript 引擎可以同时处理其他任务:执行其他脚本,处理事件等。相比于 promise.then,它只是获取 promise 的结果的一个更优雅的语法,同时也更易于读写。
module 模块#
export+import (ES6)#
- 命名导出(每个模块包含任意数量)
- 默认导出(每个模块包含一个)
export
// 命名导出
export function hello (s) {
return `hello, ${s}`;
}import xxx from ‘xxx’
<!doctype html>
<script type="module">
import {hello} from './hello.js'
alert(hello("js"));
</script>
<script nomodule>
alert("no module");
</script>也可以
import * as hello from './hello.js'nomodule
旧时的浏览器不理解 type="module", 会运行nomodule的代码块,支持 module 的浏览器不会运行该代码块。
与 Node.js 中 exports 和 required 区别
module.exports+require (node.js)#
通过 module.exports 导出:
const car = {
brand: 'Ford',
model: 'Fiesta'
}
module.exports = car在另一个文件中使用 require:
const car = require('./car')内存管理#
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Memory_Management
参考#
- 现代 JavaScript 教程 https://zh.javascript.info/
- ES6 入门教程 https://es6.ruanyifeng.com/
- JavaScript - MDN https://developer.mozilla.org/zh-CN/docs/learn/JavaScript