JavaScript
1.入门
字面量和变量
变量的内存 变量中并不存储任何值,而是存储值的内存地址!
基本类型
JavaScript 中的基本类型(如 number、string、boolean、null、undefined、symbol 和 bigint)是按值存储 的。 当你执行 let b = a; 时,JavaScript 会复制 a 的值到 b,两者存储在不同的内存空间中。
例子:
如果后来你修改了 a 或 b 的值,比如:
此时,b 的值仍然是 10,因为它们彼此独立。
引用类型
如果是对象(如数组、对象、函数等),它们是按引用存储 的。赋值时,新的变量会共享同一个引用,而不是创建副本。
例子:
1 2 3 4 let obj1 = { value : 10 };let obj2 = obj1; obj1.value = 20 ; console .log (obj2.value );
在这种情况下,obj1 和 obj2 指向同一块内存,因此修改 obj1 的属性会影响到 obj2。
常量 1 2 3 4 5 6 const PI = 3.1415926 ;
标识符 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
2.数据类型
let和const 1 2 3 4 5 6 7 8 9 10 let message = "hello" ;function foo ( ) { console .log (message); let message = "haha" ; } foo ();
数值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
类型检查 1 2 3 4 5 6 7 8 9 10 let a = 10 ;let b = 10n ;console .log (typeof a); console .log (typeof b);
字符串 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 const name = "ear" ;const age = 18 ;function foo (...args ) { console .log (args); } foo`my name is ${name} , age is ${age} , haha` ;
其他数据类型 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 let a = Symbol (); console .log (typeof a); const s1 = Symbol ("address" );const s2 = Symbol ("height" );const obj = { name : "ear" , age : 18 , [s1]: "花果山" , [s2]: 1.88 } console .log (Object .keys (obj)); console .log (Object .getOwnPropertySymbols (obj)); const s3 = Symbol ("abc" );console .log (s3.description ); const s4 = Symbol (s3.description );console .log (s3 === s4); const s5 = Symbol .for ("123" );const s6 = Symbol .for ("123" );console .log (s5 === s6);
类型转换-字符串 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 let a = 10 ;console .log (typeof a, a); a = a.toString (); console .log (typeof a, a); let b = 33 ;b = undefined ; console .log (typeof b, b); b = String (b); console .log (typeof b, b);
类型转换-数值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 let a = "123" ;console .log (typeof a, a); a = Number (a); console .log (typeof a, a); let b = "12.45c456" ;console .log (typeof b, b); c = parseInt (b); d = parseFloat (b); console .log (typeof c, c); console .log (typeof d, d);
类型转换-布尔值
类型转换 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
3.运算符
算数运算符 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 a = "a" + null ; console .log (a);
赋值运算符 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 const a = { duration : 50 }; a.speed ??= 25 ; console .log (a.speed ); a.duration ??= 10 ; console .log (a.duration );
一元的加减 1 2 3 4 5 6 7 8 9 10 11 12 let a = "123" ;a = +a; console .log (typeof a, a);
自增和自减 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 let a = 10 ; a++; console .log (a); let b = 10 ; let c = b++; console .log ("b++ =" , c); let d = 10 ; let e = ++d; console .log ("++d =" , e); let n = 5 ; let result = n++ + ++n + n console .log (result);
逻辑运算符 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 let a = 123 ;a = !!a; console .log (typeof a, a); true && alert (123 ); false && alert (456 ); let result = 1 && 2 ;console .log (result); let result2 = 1 && 0 ;console .log (result2); let result3 = 0 && NaN ;console .log (result3); true || alert (78 ); false || alert (90 );
关系运算符 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 let result = 5 < "10" ;console .log (result); let result2 = "1" > false ;console .log (result2); let result3 = "a" < "b" ;console .log (result3); let result4 = "abc" < "b" ;console .log (result3); let result5 = "12" < "2" ;console .log (result3);
相等运算符 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 let result = 1 == 1 ;console .log (result); let result2 = 1 == "1" ;console .log (result2); let result3 = null == undefined ;console .log (result3);
条件运算符 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 false ? alert (1 ) : alert (2 ); let a = 100 ;let b = 10 ;a > b ? console .log ("a大" ) : console .log ("b大" ); let max = a > b ? a : b;console .log (max);
运算符优先级
空值合并运算符(??) 空值合并运算符 (?? )是一个逻辑运算符,当左侧的操作数为 null 或者 undefined 时,返回其右侧操作数,否则返回左侧操作数。
1 2 3 4 5 6 7 const foo = null ?? 'default string' ;console .log (foo);const baz = 0 ?? 42 ;console .log (baz);
4.流程控制语句
代码块
if语句 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
if-else语句 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
switch语句 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
循环语句 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 let i = 0 ;while (1 ) { console .log (i); i++; if (i >= 5 ) { break ; } }
do-while循环 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
for循环 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
break和continue
5.对象
对象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 let obj = new Object ();let obj2 = Object ();obj.name = "孙悟空" ; obj.age = 18 ; obj.gender = "男" ; console .log (obj); console .log (obj.name );
对象的属性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 let obj = Object ();obj.name = "孙悟空" ; obj["21432sdaf" ] = "呵呵" ; let mySymbol = Symbol ();obj[mySymbol] = "通过symbol添加的属性" ; let str = "address" ;obj[str] = "花果山" ; console .log ("name" in obj); console .log ("haha" in obj);
对象的字面量 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 let mySymbol = Symbol ();let str = "address" ;let obj = { name : "孙悟空" , age : 18 , ["gender" ]: "男" , [mySymbol]: "特殊的属性" , [str]: "花果山" }; console .log (typeof obj, obj);
对象的枚举 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 let obj = { name : "孙悟空" , age : 18 , gender : "男" , [Symbol ()]: "测试属性" }; for (let propName in obj) { console .log (typeof propName); console .log (propName, obj[propName]); }
可变类型
改变量和改对象
1 2 let obj = { a : 1 }; obj = 100 ;
你改变的是变量 obj 指向的东西
1 2 let obj = { a : 1 };obj.a = 999 ;
此时没有改变 obj 指向哪儿,只是修改了它指向的那块内存的内容
方法
对象访问器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 const person = { firstName : "Bill" , lastName : "Gates" , language : "" , get fullName () { return this .firstName + " " + this .lastName ; }, set lang (lang ) { this .language = lang.toUpperCase (); } }; console .log (person.fullName ); person.lang = "en" ;
属性描述符 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 const obj = { name : "ear" , age : 18 } Object .defineProperty (obj, "name" , { configurable : false , enumerable : false , writable : false , value : "earstrive" }); delete obj.name ;console .log (obj); Object .defineProperty (obj, "address" , {});delete obj.address ;console .log (obj); console .log (Object .keys (obj)); obj.name = "kobe" ; console .log (obj.name ); const obj2 = { name : "ear" , age : 18 } let _name = obj2.name ;Object .defineProperty (obj2, "name" , { configurable : true , enumerable : false , set : function (value ) { console .log ("set方法被调用" , value); _name = value; }, get : function ( ) { console .log ("get方法被调用" ); return _name; } }); obj2.name = "kobe" ; console .log (obj2.name ); const obj3 = { name : "ear" , age : 18 , height : 1.88 } Object .defineProperties (obj3, { name : { configurable : true , enumerable : true , writable : false }, age : {}, height : {} });
6.函数
函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
函数的创建方式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 function fn ( ) { console .log ("函数声明所定义的函数" ); } const fn2 = function ( ) { console .log ("函数表达式" ); } const fn3 = ( ) => { console .log ("箭头函数" ); }
参数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
箭头函数的参数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 const fn = a => { console .log (a); } fn (123 ); const fn2 = (a = 10 , b = 20 , c = 30 ) => { console .log (a, b, c); } fn2 (1 , 2 );
对象和函数作为参数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 let obj = { name : "孙悟空" };function fn (a ) { console .log ("我是fn" ); a (); } function fn2 ( ) { console .log ("我是fn2" ); } fn (fn2);
函数的返回值
箭头函数的返回值 1 2 3 4 5 6 7 8 const sum = a => a + 1 ;console .log (sum (5 )); const fn = ( ) => ({ name : "孙悟空" });
作用域与作用域链 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 let a = 10 ;{ let a = "第一代码块中的a" ; { let a = "第二代码块中的a" ; console .log (a); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 var message = "globle message" ;function fn1 ( ) { console .log (message); var message = "fn1 message" ; } fn1 ();var obj = { name : "obj" , bar : function ( ) { var message = "bar message" ; fn1 (); } } obj.bar (); var a = 100 ;function foo ( ) { a = 200 ; } foo ();console .log (a); function fn2 ( ) { console .log (b); var b = 200 ; console .log (b); } var b = 100 ;fn2 ();var c = 100 ;function fn3 ( ) { console .log (c); } function fn4 ( ) { var c = 200 ; console .log (c); fn3 (); } fn4 ();console .log (c); var d = 100 ;function fn5 ( ) { console .log (d); return ; var d = 100 ; } fn5 (); function fn6 ( ) { e = "hello e" ; } fn6 ();console .log (e); function fn7 ( ) { var f = g = 100 ; } fn7 ();console .log (f); console .log (g);
闭包 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 function outer ( ) { let num = 0 ; return () => { num++; console .log (num); } } const newFn = outer ();console .log (newFn ());console .log (outer ()());
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 function fn1 ( ) { var arr = new Array (1024 * 1024 ).fill (1 ); return function ( ) { console .log (arr); } } var arr = [];function fn2 ( ) { for (var index = 0 ; index < 100 ; index++) { arr.push (fn1 ()); } } fn2 ();function fn3 ( ) { arr = []; } fn3 ();
函数对象的属性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 function func1 ( ) {}function func2 (a, b ) {}console .log (func1.length );console .log (func2.length );
arguments 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 function sum ( ) { let result = 0 ; for (const num of arguments ) { result += num; } return result; } function sum2 (...num ) { return num.reduce ((a, b => a + b, 0 )); } function fn (a, b, ...args ) { console .log (args); } fn (123 , 456 , "hello" , true , 2342 );
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 function fn1 ( ) { const arr1 = [] for (const arg of arguments ) { arr1.push (arg); } console .log ("arr1:" , arr1); const arr2 = Array .from (arguments ); console .log ("arr2:" , arr2); const arr3 = [...arguments ]; console .log ("arr3:" , arr3); const arr4 = [].slice .apply (arguments ); console .log ("arr4:" , arr4); } fn1 (1 , 2 , 3 , 4 , 5 );
纯函数
函数柯里化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 function fn1 (x, y, z ) { console .log (x + y + z); } function hyCurrying (fn ) { function curryFn (...args ) { if (args.length >= fn.length ) { return fn.apply (this , args); } else { return function (...nawArgs ) { return curryFn.apply (this , args.concat (nawArgs)); } } } return curryFn; } const fn1Curry = hyCurrying (fn1);fn1Curry (10 )(20 )(30 );
window对象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 { function fn ( ) { console .log (1 ); d = 10 ; } } fn (); window .fn (); console .log (d);
提升 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 console .log (a); var a = 10 ;fn1 (); function fn1 ( ) { console .log ("我是fn" ); } var b = 1 ;function fn2 ( ) { console .log (b); var b = 2 ; console .log (b); } fn2 ();console .log (b);
立即执行函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 (function ( ) { console .log ("立即执行函数" ); }());
this 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 function fn ( ) { console .log (this === window ); } fn (); const obj = { name : "孙悟空" };obj.test = fn; obj.test ();
默认绑定 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 function fn1 ( ) { console .log ("独立函数调用this-->" , this ); } fn1 (); const obj = { name : "ear" , fn2 : function ( ) { console .log ("this-->" , this ); } } const fn3 = obj.fn2 ;obj.fn2 (); fn3 (); function fn4 (fn ) { fn (); } fn4 (fn1);
隐式绑定 1 2 3 4 5 6 7 8 9 10 function fn1 ( ) { console .log ("this-->" , this ); } const obj = { name : "ear" , fn2 : fn1 } obj.fn2 ();
new关键字绑定 1 2 3 4 5 6 7 8 9 10 11 12 13 14 function fn1 ( ) { this .name = "ear" ; console .log ("this-->" , this ); } new fn1 ();
显式绑定 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 function fn1 ( ) { console .log ("this-->" , this ); } const obj = { name : "ear" } fn1.call (obj); fn1.call (123 ); fn1.apply ("sunwukong" ); fn1.apply (undefined ); const fn2 = fn1.bind (obj);fn2 ();
call和apply 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 function fn (a, b ) { console .log ("函数执行了" , this ); console .log (a, b); } const obj = { name : "孙悟空" }fn (); fn.call (obj, 1 , 2 ); fn.apply (obj, [3 , 4 ]);
bind 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 function fn (a, b, c ) { console .log ("fn执行了" , this ); console .log (a, b, c); } const obj = { name : "孙悟空" }const newFn = fn.bind (obj, 10 );newFn (20 , 30 );
绑定优先级 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 function fn1 ( ) { console .log ("this-->" , this ); } const obj = { name : "ear" , fn1 } obj.fn1 .apply ("aaa" ); const fn2 = fn1.bind (123 );const obj2 = { name : "sunwukong" , fn2 } obj2.fn2 ();
箭头函数的this 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 function fn ( ) { console .log (this ); } const fn2 = ( ) => { console .log (this ); } const obj = { name : "孙悟空" , fn, fn2, sayHello ( ) { console .log (this .name ); function t1 ( ) { console .log ("t1-->" , this ); const t4 = ( ) => { console .log ("t4-->" , this ); } t4 (); } const t2 = ( ) => { console .log ("t2-->" , this ); const t3 = ( ) => { console .log ("t3-->" , this ); } t3 (); } t1 (); t2 (); } } obj.fn (); obj.fn2 (); obj.sayHello ();
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 const fn = ( ) => { console .log ("this-->" , this ); } const obj = { name : "ear" , fn } fn (); obj.fn (); fn.call (obj);
严格模式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 "use strict"
额外知识 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 const obj = { name : "ear" } with (obj) { console .log (name); }
7.面向对象
面向对象
类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class Person { }const p1 = new Person ();console .log (p1 instanceof Person );
属性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Person { name = "孙悟空" ; age = 18 ; static test = "test静态属性" ; static hh = "静态属性" ; } const p1 = new Person ();console .log (p1); console .log (p1.name ); console .log (Person .test );
方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Person { name = "孙悟空" ; test1 = function ( ) { } test2 ( ) { console .log (this ); } static test3 ( ) { console .log (this ); } } const p1 = new Person ();p1.test2 (); Person .test3 ();
构造函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Person { name; age; gender; constructor (name, age, gender ) { console .log ("构造函数执行了" , name, age, gender); this .name = name; this .age = age; this .gender = gender; } } const p1 = new Person ("孙悟空" , 18 , "男" );
封装 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 class Person { #name; #age; #gender; constructor (name, age, gender ) { this .#name = name; this .#age = age; this .#gender = gender; } sayHello ( ) { console .log (this .#name); } getName ( ) { return this .#name; } setName (name ) { this .#name = name; } get age () { return this .#age; } set age (age ) { this .#age = age; } } const p1 = new Person ("孙悟空" , 18 , "男" );p1.setName ("猪八戒" ); p1.age = 28 ; console .log (p1.age );
多态
继承 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 class Animal { constructor (name ) { this .name = name; } sayHello ( ) { console .log ("动物在叫" ); } } class Dog extends Animal { sayHello ( ) { console .log ("汪汪汪" ); } } class Cat extends Animal { constructor (name, age ) { super (name); this .age = age; } sayHello ( ) { super .sayHello (); console .log ("喵喵喵" ); } } const dog = new Dog ("旺财" );const cat = new Cat ("汤姆" , 3 );dog.sayHello (); cat.sayHello (); console .log (dog.name ); console .log (cat.name , cat.age );
对象的结构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class Person { name = "孙悟空" ; age = 18 ; sayHello = "hello" ; sayHello ( ) { console .log ("hello" ); } } const p1 = new Person ();console .log (p1.sayHello );
原型与原型链 普通对象的原型
函数对象的原型 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 const obj = {}function foo ( ) { }console .log (obj.__proto__ );console .log (foo.__proto__ );console .log (obj.prototype ); console .log (foo.prototype );function Student (name, age ) { this .name = name; this .age = age; } Student .prototype .running = function ( ) { console .log (this .name + "running" ); } const stu1 = new Student ("ear" , 18 );stu1.running ();
显式原型的属性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 function Person ( ) { }console .log (Person .prototype );console .log (Person .prototype .constructor );console .log (Person .prototype .constructor === Person ); console .log (Person .name ); console .log (Person .prototype .constructor .name ); const p = new Person ();console .log (p.__proto__ .constructor );console .log (p.__proto__ .constructor .name );
借用构造函数实现继承 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 function Person (name, age, height, address ) { this .name = name; this .age = age; this .height = height; this .address = address; } Person .prototype .running = function ( ) { console .log ("running" ); } Person .prototype .eating = function ( ) { console .log ("earing" ); } function Student (name, age, height, address, sno, score ) { Person .call (this , name, age, height, address); this .sno = sno; this .score = score; } const s = new Student ("zhangsan" , 18 , 1.88 , "花果山" , 1 , 20 );console .log (s);
原型对象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 class Person { name = "孙悟空" ; age = 18 ; sayHello ( ) { console .log (this .name ); } } const p = new Person ();console .log (p); console .log (p.__proto__ ); console .log (Object .getPrototypeOf (p) === p.__proto__ ); console .log (p.__proto__ .__proto__ );console .log (p.__proto__ .__proto__ .__proto__ );
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 class Person { name = "孙悟空" sayHello ( ) { } sayHello2 = () => { } } const p1 = new Person ();const p2 = new Person ();console .log (p1.__proto__ === p2.__proto__ ); console .log (p1.sayHello === p2.sayHello ); console .log (p1.sayHello2 === p2.sayHello2 ); class Animal { }class Cat extends Animal { }const cat = new Cat ();
修改原型对象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class Person {} const p = new Person ();console .log (Person .prototype === p.__proto__ ); Person .prototype .fly = () => { console .log ("我在飞" ); } console .log (p.fly ());
instanceof和hasOwn 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 class Animal { }class Dog extends Animal { }const dog = new Dog ();console .log (dog instanceof Dog ); console .log (dog instanceof Animal ); console .log (dog instanceof Object ); class Person { name = "孙悟空" ; age = 18 ; sayHello ( ) { console .log (this .name ); } } const p = new Person ();console .log (p.hasOwnProperty ("sayHello" )); console .log (Object .hasOwn (p, "name" ));
new运算符
总结 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
8.数组
简介 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 const arr = new Array ();const arr2 = [1 , 2 , 3 , 4 , 5 ];arr2[100 ] = 99 ; console .log (arr2); arr[arr.length ] = 1 ; arr[arr.length ] = 2 ; arr[arr.length ] = 3 ; console .log (arr); console .log (typeof arr);
Array() 构造函数
Array.prototype.fill()
遍历数组 1 2 3 4 5 6 7 8 9 10 11 12 let arr = [1 , "hello" , true , null , { name : "孙悟空" }, () => { }];for (let i = 0 ; i < arr.length ; i++) { console .log (arr[i]); }
for-of 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 const arr = ["孙悟空" , "猪八戒" , "沙和尚" , "唐僧" ];for (const value of arr) { console .log (value); }
数组的方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 const arr = ["孙悟空" , "猪八戒" , "沙和尚" , "唐僧" , "猪八戒" ];const arr2 = ["白骨精" , "蜘蛛精" , "玉兔精" ];console .log (Array .isArray (arr)); console .log (arr.at (-2 )); console .log (arr.concat (arr2)); console .log (arr.indexOf ("猪八戒" )); console .log (arr.indexOf ("猪八戒" , 3 )); console .log (arr.lastIndexOf ("猪八戒" , 3 )); console .log (arr.lastIndexOf ("猪八" )); console .log (arr.join ("@" )); console .log (arr.slice (0 , 2 ));
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 const arr = [1 , 2 , 3 , 4 ];console .log (arr.push (5 , "haha" )); console .log (arr); console .log (arr.pop ()); console .log (arr); console .log (arr.unshift ("xixi" )); console .log (arr); console .log (arr.shift ()); console .log (arr); const arr2 = [1 , 2 , 3 , 4 ];console .log (arr2.splice (1 , 2 , "haha" , "xixi" )); console .log (arr2); console .log (arr2.splice (1 , 0 , "gugu" )); console .log (arr2); const arr3 = [5 , 4 , 3 , 2 , 1 ];console .log (arr3.reverse ()); console .log (arr3);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 const arr = [1 , 3 , 4 , 10 , 22 , 45 , 2 , 4 , 8 , 5 , 8 ];console .log (arr.sort ()); console .log (arr.sort ((a, b ) => a - b)); console .log (arr.sort ((a, b ) => b - a)); const arr2 = ["a" , "b" , "c" , "d" , "e" , "f" ];arr2.forEach ((element, index, array ) => { console .log (element, index, array); }) console .log (arr.filter (ele => ele % 2 === 0 )); console .log (arr2.map (ele => ele + "hello" )); const arr3 = [1 , 2 , 3 , 4 , 5 , 6 ];console .log (arr3.reduce ((a, b ) => a + b, 10 ));
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 const arr = [1 , 2 , 3 , 4 , 5 , [2 , 3 , 4 , 5 ], [[2 , 3 ], [4 , 5 ]]];const arr2 = arr.flat (1 );const arr3 = arr.flat (2 );console .log (arr2); console .log (arr3); const arr4 = arr.flatMap (arr => arr);console .log (arr4);
对象的复制 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 const arr = [1 , 2 , 3 , 4 ];const arr2 = arr.slice ();const arr3 = [...arr];console .log (arr2); console .log (arr3); console .log (arr === arr2); console .log (arr === arr3); const obj = { name : "孙悟空" , age : 18 }const obj2 = Object .assign ({}, obj);const obj3 = { ...obj }console .log (obj2); console .log (obj === obj2); console .log (obj3); console .log (obj === obj3);
浅拷贝和深拷贝 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 const arr = [{ name : "孙悟空" }, { name : "猪八戒" }]; const arr2 = arr.slice (); const arr3 = structuredClone (arr); console .log (arr === arr2); console .log (arr[0 ] === arr2[0 ]); console .log (arr === arr3); console .log (arr[0 ] === arr3[0 ]); const obj = { name : "孙悟空" , friend : { name : "猪八戒" } } const obj2 = Object .assign ({}, obj); const obj3 = structuredClone (obj); const obj4 = JSON .parse (JSON .stringify (obj));
排序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 const arr = [9 , 1 , 3 , 2 , 8 , 0 , 5 , 7 , 6 , 4 ];for (let i = 0 ; i < arr.length - 1 ; i++) { for (let j = 0 ; j < arr.length - 1 - i; j++) { if (arr[j] > arr[j + 1 ]) { let temp = arr[j]; arr[j] = arr[j + 1 ]; arr[j + 1 ] = temp; } } } console .log (arr); const arr2 = [9 , 1 , 3 , 2 , 8 , 0 , 5 , 7 , 6 , 4 ];for (let i = 0 ; i < arr2.length ; i++) { for (let j = i + 1 ; j < arr2.length ; j++) { if (arr2[i] > arr2[j]) { let temp = arr2[i]; arr2[i] = arr2[j]; arr2[j] = temp; } } } console .log (arr2);
高阶函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 class Person { #name; #age; constructor (name, age ) { this .#name = name; this .#age = age; } get name () { return this .#name; } get age () { return this .#age; } } const personArr = [ new Person ("孙悟空" , 18 ), new Person ("猪八戒" , 28 ), new Person ("沙和尚" , 38 ), new Person ("唐僧" , 48 ) ]; const arr = [1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ];function filter (arr, cb ) { const newArr = []; for (let i = 0 ; i < arr.length ; i++) { if (cb (arr[i])) { newArr.push (arr[i]); } } return newArr; } console .log (filter (personArr, a => a.age > 20 ));console .log (filter (arr, a => a % 2 === 0 )); function someFn ( ) { return "hello" ; } function outer (cb ) { return () => { console .log ("记录日志" ); const result = cb (); return result; } } let fn = outer (someFn);console .log (fn ());console .log (outer (someFn)());
递归 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 function jieCheng (num ) { if (num === 1 ) { return 1 ; } return jieCheng (num - 1 ) * num; } console .log (jieCheng (5 ));
9.内建对象
结构赋值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 const arr = ["孙悟空" , "猪八戒" , "沙和尚" ]; let [a, b, c = 7 , d = 10 ] = arr; console .log (a, b, c, d); let [n1, n2, ...n3] = [1 , 2 , 3 , 4 , 5 , 6 ]; console .log (n1, n2, n3); let a1 = 10 ; let a2 = 20 ; [a1, a2] = [a2, a1]; console .log (a1, a2); const obj = { name : "孙悟空" , age : 18 , gender : "男" } let { name, age, gender } = obj; console .log (name, age, gender); let { address } = obj; console .log (address); let { name : a, age : b, gender : c, address :d = "china" } = obj; console .log (a, b, c);
对象的序列化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 const obj = { name : "孙悟空" , age : 18 } const str = JSON .stringify (obj);console .log (str); const obj2 = JSON .parse (str);console .log (obj2);
Map 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 const map = new Map ();const obj = { name : "孙悟空" }map.set (obj, "haha" ); map.set (NaN , "xixi" ); console .log (map.get (NaN )); map.delete (NaN ); console .log (map.has (obj)); map.clear (); const map2 = new Map ();map2.set ("name" , "孙悟空" ); map2.set ({}, "hehe" ); const arr = Array .from (map2);const arr2 = [...map2];console .log (arr, arr2);
Set 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 const set = new Set ();set.add (10 ); set.add ("孙悟空" ); set.add (10 ); console .log (set); const num = [1 , 2 , 3 , 4 , 5 , 6 , 2 , 3 , 4 , 3 , 2 ];const newNumSet = new Set (num);const newNum = Array .from (newNumSet); console .log (newNum); const obj = {}const weakSet = new WeakSet ();weakSet.add (obj);
Math 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Date 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 let d = new Date (); console .log (d);console .log (d.getFullYear ());console .log (d.getMonth ());console .log (d.getDate ());console .log (d.getDay ());console .log (d.getTime ());
日期的格式化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 const d = new Date ();let result = d.toLocaleDateString ();let result2 = d.toLocaleTimeString ();let result3 = d.toLocaleString ()console .log (result); console .log (result2); console .log (result3); let result4 = d.toLocaleString ("zh-CN" , { year : "numeric" , month : "long" , day : "2-digit" , weekday : "short" }); console .log (result4);
包装类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 let num = 11 ;num = num.toString (); console .log (typeof num);
字符串方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 let str = "hello" ;console .log (str.length ); console .log (str.at (-1 )); let str2 = "hello how are you" ;console .log (str2.includes ("how" , 2 )); let str3 = "1" ;console .log (str3.padStart (5 , "0" )); let str4 = "hello hello how are you" ;console .log (str4.replace ("hello" , "happy" )); console .log (str4.slice (0 , 5 )); let str5 = "sadf@kjh@hkj@hkefj@hfd" ;console .log (str5.split ("@" ));
正则表达式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 let reg = new RegExp ("a" , "i" ); let reg2 = /a/i ;console .log (reg, reg2);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 let reg = /ab/ ;console .log (reg.test ("abc" )); let reg2 = /a|b/ ;console .log (reg2.test ("ac" )); let reg3 = /[a-z]/ ;console .log (reg3.test ("ac" )); let reg4 = /[^a-z]/ ;console .log (reg4.test ("ac" )); let reg5 = /\w/ ;console .log (reg5.test ("ac" )); let reg6 = /^a/ ;console .log (reg6.test ("ba" )); let reg7 = /a$/ ;console .log (reg7.test ("ba" )); let reg8 = /a{3}/ ;console .log (reg8.test ("aaa" )); let reg9 = /^[a-z]{1,4}$/ ;console .log (reg9.test ("aaajjj" )); let str = "abcaecafcacc" ;let re = /a[a-z]c/ig ;console .log (re.exec (str));console .log (re.exec (str));let str2 = "asgia15345678911ogdsjgoegri18745632111ndsothh14158296311aegrjesg" ;let re2 = /(1[3-9]\d)\d{4}(\d{4})/g ;let result;while (result = re2.exec (str2)) { console .log (result[0 ], result[1 ], result[2 ]); console .log (result[1 ] + "****" + result[2 ]); }
字符串的正则表达式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 let str = "孙悟空abc猪八戒adc沙和尚" console .log (str.split (/a[bd]c/ )); let str2 = "asgia15345678911ogdsjgoegri18745632111ndsothh14158296311aegrjesg" ;console .log (str2.search (/1[3-9]\d{9}/ )); console .log (str2.replace (/1[3-9]\d{9}/g , "哈哈哈" )); console .log (str2.match (/1[3-9]\d{9}/g ));
垃圾回收
Proxy 监听对象属性操作(Vue2原理) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 const obj = { name : "ear" , age : 18 } let _name = obj.name ;Object .defineProperty (obj, "name" , { set : function (newValue ) { console .log ("监听:给name设置了新的值:" , newValue); _name = newValue; }, get : function ( ) { console .log ("监听:获取name值" ); return _name; } }); console .log (obj.name ); obj.name = "sunwukong" ; console .log (obj.name ); console .log ("------------------------------" );const obj2 = { name : "ear" , age : 18 } const keys = Object .keys (obj2);keys.forEach (ele => { let value = obj2[ele]; Object .defineProperty (obj2, ele, { set : function (newValue ) { console .log (`监听:给${ele} 设置了新的值:` , newValue); value = newValue; }, get : function ( ) { console .log (`监听:获取${ele} 值` ); return value; } }) }); obj2.name = "sunwukong" ; console .log (obj2.name ); obj2.age = 16 ;
监听对象属性操作(Vue3原理) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 const obj = {name : "ear" ,age : 18 } const objProxy = new Proxy (obj, {get (target, key ) { console .log (`监听${key} 的获取` ); return target[key]; }, set (target, key, newValue ) { console .log (`监听${key} 的设置` ); target[key] = newValue; } }); console .log (objProxy.name ); objProxy.age = 17 ; console .log (objProxy.age );
其他捕获器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 const obj = {name : "ear" ,age : 18 } const objProxy = new Proxy (obj, {get (target, key ) { console .log (`监听${key} 的获取` ); return target[key]; }, set (target, key, newValue ) { console .log (`监听${key} 的设置` ); target[key] = newValue; }, deleteProperty (target, key ) { console .log (`监听${key} 的删除` ); delete target[key]; }, has (target, key ) { console .log (`监听in判断${key} 属性` ); return key in target; } }); delete objProxy.age ; console .log (objProxy); console .log ("name" in objProxy);
Reflect Reflect和Object的一些区别 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 const obj = { name : "ear" , age : 18 } Object .defineProperty (obj, "name" , { configurable : false }); if (Reflect .deleteProperty (obj, "name" )) { console .log ("name删除成功" ); } else { console .log ("name没有删除成功" ); }
Reflect和Proxy共同完成代理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 const obj = { _address : "China" , name : "why" , age : 18 , get address () { return this ._address ; }, set address (newValue ) { console .log ("this:" , this ); this ._address = newValue; } } const objProxy = new Proxy (obj, { set (target, key, newValue, receiver ) { console .log ("proxy中设置方法被调用" ); const isSuccess = Reflect .set (target, key, newValue, receiver); if (!isSuccess) throw new Error (`set ${key} failure` ); }, get (target, key, receiver ) { console .log ("proxy中获取方法被调用" ); return Reflect .get (target, key, receiver); } }); objProxy.address = "USA" ; console .log (objProxy.address );
Promise 传统解决异步和Promise解决异步的区别 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 function execCode (counter, successCallBack, failureCallBack ) { setTimeout (() => { if (counter > 0 ) { let total = 0 ; for (let i = 0 ; i < counter; i++) { total += i; } successCallBack (total); } else { failureCallBack (`${counter} 值有问题` ); } }, 3000 ); } execCode (100 , value => { console .log ("执行成功:" , value); }, (err ) => { console .log ("执行失败:" , err); }); function execCode (counter ) { return new Promise ((resolve, reject ) => { setTimeout (() => { if (counter > 0 ) { let total = 0 ; for (let i = 0 ; i < counter; i++) { total += i; } resolve (total); } else { reject (`${counter} 有问题` ); } }, 3000 ); }); } execCode (100 ).then (res => { console .log ("成功:" , res); }).catch (err => { console .log ("失败:" , err); });
Promise的各种状态区分 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 const promise = new Promise ((resolve, reject ) => { console .log ("待定状态" ); resolve (); reject (); }); promise.then (value => { console .log ("成功的回调" ); }).catch (err => { console .log ("失败的回调" ); });
Promise中resolve的值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 const p = new Promise (resolve => { setTimeout (resolve ("p的resolve" ), 2000 ); }); const promise = new Promise ((resolve, reject ) => { resolve (123 ); resolve (false ); resolve ({ name : "ear" }); resolve (p); resolve ({ name : "ear" , then (resolve ) { resolve ("对象中的then-resolve" ); } }) }); promise.then (res => { console .log ("then中拿到的结果:" , res); })
Promise中then和catch的调度 1 2 3 4 5 6 7 8 const promise = new Promise ((resolve, reject ) => { reject ("failure" ); }); promise.then (res => console .log (res)) .catch (err => console .log (err));
Promise中reject和error 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 const promise1 = new Promise ((resolve, reject ) => { throw new Error ("错误,Error" ); console .log (123 ); }); promise1.then (res => console .log (res)) .catch (err => console .log (err)); const promise2 = new Promise ((resolve, reject ) => { reject ("错误,reject" ); console .log (123 ); }) promise2.then (res => console .log (res)) .catch (err => console .log (err));
Promise中then的返回值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 const promise = new Promise ((resolve, reject ) => { resolve ("1111111" ); }); const newPromise = new Promise ((resolve, reject ) => { setTimeout (resolve ("新的Promise" ), 3000 ); }); promise.then (res => { console .log ("第一个then方法:" , res); return "2222222" ; }).then (res => { console .log ("第二个then方法:" , res); return "普通值" ; }).then (res => { console .log ("第三个then方法:" , res); return newPromise; }).then (res => { console .log ("第四个then方法" , res); return { then (resolve ) { resolve ("thenable值" ); } } }).then (res => console .log ("第五个then方法" , res));
Promise中catch的返回值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 const promise = new Promise ((resovle, reject ) => { reject ("1111111" ); }); promise.then (res => { console .log ("第一个then的回调" , res); }).catch (err => { console .log ("catch回调" , err); return "2222222" ; }).then (res => { console .log ("then的第一个回调" , res); }); const promise2 = new Promise ((resolve, reject ) => { resolve ("aaaaaaa" ); }); promise2.then (res => { console .log ("then的第一次回调" , res); throw new Error ("第一个then的异常error" ); return "bbbbbbb" ; }).then (res => { console .log ("then的第二次回调" , res); throw new Error ("第二个then的异常error" ); return "ccccccc" }).catch (err => { console .log ("catch回调执行" , err); });
Promise中finally的回调 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 const promise = new Promise ((resolve, reject ) => { reject ("2222222" ); }); promise.then (res => { console .log ("then的回调" , res); }).catch (err => { console .log ("catch的回调" , err); }).finally (() => { console .log ("finally的回调" ); });
Promise的类方法 1 2 3 4 5 6 7 8 9 10 11 12 const promise = Promise .resolve ("1111111" );promise.then (res => console .log ("then的结果:" , res)); const promise2 = Promise .reject ("2222222" );promise2.catch (err => console .log ("err的结果:" , err));
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 const p1 = new Promise ((resolve, reject ) => { setTimeout (() => { reject ("p1 reject" ); }, 2000 ); }); const p2 = new Promise ((resolve, reject ) => { setTimeout (() => { resolve ("p1 resolve" ); }, 3000 ); }); const p3 = new Promise ((resolve, reject ) => { setTimeout (() => { resolve ("p1 resolve" ); }, 10000 ); }); Promise .all ([p1, p2, p3]).then (res => { console .log ("all promise res:" , res); }).catch (err => { console .log ("all promise err:" , err); }); Promise .allSettled ([p1, p2, p3]).then (res => { console .log ("allSettled promise res:" , res); }).catch (err => { console .log ("allSettled promise err:" , err); }); Promise .race ([p1, p2, p3]).then (res => { console .log ("race promise res:" , res); }).catch (err => { console .log ("rece promise err:" , err); }); Promise .any ([p1, p2, p3]).then (res => { console .log ("any promise res:" , res); }).catch (err => { console .log ("any promise err:" , err); });
Iterator和Generator 迭代器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 const names = ["abc" , "bca" , "cab" ];const createArrayIterator = arr => { let index = 0 ; return { next ( ) { if (index < arr.length ) { return { done : false , value : arr[index++] } } else { return { done : true } } } } } const namesInerator = createArrayIterator (names); console .log (namesInerator.next ()); console .log (namesInerator.next ()); console .log (namesInerator.next ()); console .log (namesInerator.next ());
可迭代对象-创建可迭代对象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 const infos = { friends : ["kobe" , "james" , "curry" ], [Symbol .iterator ]: function ( ) { let index = 0 ; const infosIterator = { next ( ) { if (index < infos.friends .length ) { return { done : false , value : infos.friends [index++] } } else { return { done : true } } } } return infosIterator; } } const iterator = infos[Symbol .iterator ]();console .log (iterator.next ()); console .log (iterator.next ()); console .log (iterator.next ()); console .log (iterator.next ()); for (const item of infos) { console .log (item); } const students = ["张三" , "李四" , "王五" ];const studentIterator = students[Symbol .iterator ]();console .log (studentIterator.next ()); console .log (studentIterator.next ()); console .log (studentIterator.next ()); console .log (studentIterator.next ()); const infos = { friends : ["kobe" , "james" , "curry" ], [Symbol .iterator ]: function ( ) { let index = 0 ; const infosIterator = { next : () => { if (index < this .friends .length ) { return { done : false , value : this .friends [index++] } } else { return { done : true } } } } return infosIterator; } }
可迭代对象的应用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 const info = { name : "why" , age : 18 , height : 1.88 , [Symbol .iterator ]: function ( ) { const values = Object .values (this ); let index = 0 ; const iterator = { next : () => { if (index < values.length ) { return { done : false , value : values[index++] } } else { return { done : true } } } } return iterator; } } function foo (arg1, arg2, arg3 ) { console .log (arg1, arg2, arg3); } foo (...info); const set = new Set (["aaa" , "bbb" , "ccc" ]);const set2 = new Set ("abc" );console .log (set); console .log (set2);
自定义类的迭代 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Person { constructor (name, age, height, friend ) { this .name = name; this .age = age; this .height = height; this .friend = friend; } [Symbol .iterator ]() { let index = 0 ; return { next : () => { if (index < this .friend .length ) { return { done : false , value : this .friend [index++] } } else { return { done : true } } } } } } const p1 = new Person ("ear" , 18 , 1.88 , ["a" , "b" , "c" ]);for (const item of p1) { console .log (item); }
迭代器的中断 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class Person { constructor (name, age, height, friend ) { this .name = name; this .age = age; this .height = height; this .friend = friend; } [Symbol .iterator ]() { let index = 0 ; return { next : () => { if (index < this .friend .length ) { return { done : false , value : this .friend [index++] } } else { return { done : true } } }, return : () => { console .log ("监听到迭代器中断了" ); return { done : true } } } } } const p1 = new Person ("ear" , 18 , 1.88 , ["a" , "b" , "c" ]);for (const item of p1) { console .log (item); if (item === "b" ) break ; }
生成器函数的基本使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 function * foo (name1 ) { console .log ("执行内部代码:1111" , name1); console .log ("执行内部代码:2222" , name1); const name2 = yield "aaaa" ; console .log ("执行内部代码:3333" , name2); console .log ("执行内部代码:4444" , name2); const name3 = yield "bbbb" ; console .log ("执行内部代码:5555" , name3); console .log ("执行内部代码:6666" , name3); } const generator = foo ("next1" );console .log (generator.next ()); console .log (generator.next ("next2" )); console .log (generator.next ("next3" )); const names = ["abc" , "cab" , "nba" ];function * createArrayIterator (arr ) { for (let i = 0 ; i < arr.length ; i++) { yield arr[i]; } } const namesIterator = createArrayIterator (names);console .log (namesIterator.next ()); console .log (namesIterator.next ()); console .log (namesIterator.next ()); console .log (namesIterator.next ()); function * createRangeGenerator (start, end ) { for (let i = start; i < end; i++) { yield i; } } const rangeGen = createRangeGenerator (3 , 5 );console .log (rangeGen.next ()); console .log (rangeGen.next ()); console .log (rangeGen.next ());
生成器yield的语法糖 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 const names = ["abc" , "cba" , "nba" ];function * createArrayIterator (arr ) { yield * arr; } const nameIterator = createArrayIterator (names);console .log (nameIterator.next ()); console .log (nameIterator.next ()); console .log (nameIterator.next ()); console .log (nameIterator.next ()); class Person { constructor (name, age, height, friends ) { this .name = name; this .age = age; this .height = height; this .friends = friends; } *[Symbol .iterator ]() { yield * this .friends ; } } const p = new Person ("ear" , 18 , 1.88 , ["kobe" , "james" , "curry" ]);for (const item of p) { console .log (item); }
异步函数async-await 异步函数的返回值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 async function foo ( ) { return 123 ; } foo ().then (res => { console .log ("res:" , res); });
异步函数的异常 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 async function foo ( ) { throw new Error ("ear async function error" ); } foo ().then (res => { console .log ("res:" , res); }).catch (err => { console .log ("ear err" , err); });
await的使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 function bar ( ) { return new Promise (resolve => { setTimeout (() => { resolve (123 ); }, 2000 ); }); } async function foo ( ) { try { const res1 = await bar (); console .log ("res1:" , res1); const res2 = await bar (); console .log ("res2:" , res2); } catch (error) { console .log ("err:" , error); } } foo ();
异步代码如何执行 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
事件循环
微任务和宏任务的区别 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 console .log ("11111" );new Promise (resolve => { console .log ("22222" ); resolve (); console .log ("33333" ); }).then (res => { console .log ("44444" ); }); console .log ("55555" );
代码执行顺序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
防抖和节流 防抖函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 function eardebounce (fn, delay, immediate = false ) { let timer = null ; let isInvoke = false ; const _debounce = function (...args ) { return new Promise ((resolve, reject ) => { try { if (timer) clearTimeout (timer); let res = undefined ; if (immediate && !isInvoke) { res = fn.apply (this , args); resolve (res); isInvoke = true ; return ; } timer = setTimeout (() => { res = fn.apply (this , args); resolve (res); timer = null ; isInvoke = false ; }, delay); } catch (error) { reject (error); } }); } _debounce.cancel = () => { if (timer) clearTimeout (timer); timer = null ; isInvoke = false ; } return _debounce; }
节流函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 function earthrottle (fn, interval, { leading = true , trailing = true } = {} ) { let startTime = 0 ; let timer = null ; const _throttle = function (...args ) { return new Promise ((resolve, reject ) => { try { const nowTime = new Date ().getTime (); if (!leading && startTime === 0 ) { startTime = nowTime; } const waitTime = interval - (nowTime - startTime); if (waitTime <= 0 ) { if (timer) clearTimeout (timer); const res = fn.apply (this , args); resolve (res); startTime = nowTime; timer = null ; return ; } if (trailing && !timer) { timer = setTimeout (() => { const res = fn.apply (this , args); resolve (res); startTime = new Date ().getTime (); timer = null ; }, waitTime); } } catch (error) { reject (error); } }) } _throttle.cancel = function ( ) { if (timer) clearTimeout (timer); startTime = 0 ; timer = null ; } return _throttle; }
深拷贝 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 const isObject = value => { const valueType = typeof value; return (value !== null ) && (valueType === "object" || valueType === "function" ); } const deepCopy = (originValue, map = new Map () ) => { if (typeof originValue === "symbol" ) { return Symbol (originValue.description ); } if (!isObject (originValue)) return originValue; if (originValue instanceof Set ) { const newSet = new Set (); for (const setItem of originValue) { newSet.add (deepCopy (setItem, map)); } return newSet; } if (originValue instanceof Map ) { const newMap = new Map (); for (const [key, value] of originValue) { newMap.set (key, deepCopy (value, map)); } return newMap; } if (typeof originValue === "function" ) return originValue; if (map.get (originValue)) return map.get (originValue); const newObj = Array .isArray (originValue) ? [] : {}; map.set (originValue, newObj); for (const key in originValue) { newObj[key] = deepCopy (originValue[key], map); } const symbolKeys = Object .getOwnPropertySymbols (originValue); for (const symbolKey of symbolKeys) { newObj[Symbol (symbolKey.description )] = deepCopy (originValue[symbolKey], map); } return newObj; } const info = { name : "ear" , age : 18 , friend : { name : "kobe" , address : { name : "洛杉矶" , detail : "斯坦普斯中心" } }, set : new Set (["abc" , "cba" , "bac" ]), symbolKey : Symbol ("abc" ), [Symbol ("s1" )]: "aaa" , [Symbol ("s2" )]: "bbb" } info.info = info; const newObj = deepCopy (info);console .log (newObj);console .log (newObj === newObj.info );
EventBus 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 class EarEventBus { eventMap = {} on (eventName, eventFn ) { let eventFns = this .eventMap [eventName]; if (!eventFns) { eventFns = []; this .eventMap [eventName] = eventFns; } eventFns.push (eventFn); } off (eventName, eventFn ) { let eventFns = this .eventMap [eventName]; if (!eventFns) return ; this .eventMap [eventName] = eventFns.filter (fn => fn !== eventFn); if (eventFns.length === 0 ) delete this .eventMap [eventName]; } emit (eventName, ...args ) { let eventFns = this .eventMap [eventName]; if (!eventFns) return ; eventFns.forEach (fn => { fn (...args); }); } } const eventBus = new EarEventBus ();eventBus.on ("navClick" , (name, age, height ) => { console .log ("navClick listener 01" , name, age, height); }); const click = ( ) => { console .log ("navClick listener 02" ); } eventBus.on ("navClick" , click); setTimeout (() => { eventBus.off ("navClick" , click); }, 5000 ); const navBtnEl = document .querySelector (".nav-btn" );navBtnEl.onclick = () => { eventBus.emit ("navClick" , "ear" , 18 , 1.88 ); }
XHR-Fetch XHR-XHR的基本使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 const xhr = new XMLHttpRequest ();xhr.onreadystatechange = () => { if (xhr.readyState !== XMLHttpRequest .DONE ) return ; const resJSON = JSON .parse (xhr.response ); console .log (resJSON); } xhr.open ("get" , "http://123.207.32.32:8000/home/multidata" ); xhr.send ();
XHR-XML的响应数据与类型 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 const xhr = new XMLHttpRequest ();xhr.onload = () => { console .log (xhr.response ); } xhr.responseType = "json" ; xhr.open ("get" , "http://123.207.32.32:8000/home/multidata" ); xhr.send ();
XHR-GET-POST请求传参 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 const formEl = document .querySelector (".info" );const sendBtn = document .querySelector (".send" );sendBtn.onclick = () => { const xhr = new XMLHttpRequest (); xhr.onload = () => { console .log (xhr.response ); } xhr.responseType = "json" ; xhr.open ("post" , "http://123.207.32.32:1888/02_param/postjson" ); xhr.setRequestHeader ("Content-type" , "application/json" ); xhr.send (JSON .stringify ({ name : "ear" , age : 18 })); }
XHR-AJAX网络请求封装Promise 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 const earAjax = ({ url, method = "get" , data = {}, success, failure } = {} ) => { return new Promise ((resolve, reject ) => { const xhr = new XMLHttpRequest (); xhr.onload = () => { if (xhr.status >= 200 && xhr.status < 300 ) { resolve (xhr.response ); } else { reject ({ status : xhr.status , message : xhr.statusText }); } } xhr.responseType = "json" ; if (method.toUpperCase () === "GET" ) { const queryStrings = []; for (const key in data) { queryStrings.push (`${key} =${data[key]} ` ); } url = url + "?" + queryStrings.join ("&" ); xhr.open (method, url); xhr.send (); } else { xhr.open (method, url); xhr.setRequestHeader ("Content-type" , "application/json" ); xhr.send (JSON .stringify (data)); } }); } earAjax ({ url : "http://123.207.32.32:1888/02_param/get" , method : "GET" , data : { name : "why" , age : 18 } }).then (res => console .log ("res:" , res)) .catch (err => console .log ("err:" , err));
Fetch-Fetch的基本使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 const formData = new FormData ();formData.append ("name" , "ear" ); formData.append ("age" , 18 ); fetch ("http://123.207.32.32:1888/02_param/postform" , { method : "post" , body : formData }).then (res => res.json ()).then (res => console .log (res)); fetch ("http://123.207.32.32:1888/02_param/postjson" , { method : "post" , headers : { "Content-type" : "application/json" }, body : JSON .stringify ({ name : "ear" , age : 18 }) }).then (res => res.json ()).then (res => console .log (res)); fetch ("http://123.207.32.32:1888/02_param/posturl" , { method : "post" , headers : { "Content-type" : "application/x-www-form-urlencoded" }, body : "name=ear&age=18" }).then (res => res.json ()).then (res => console .log (res));
文件上传 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 const uploadBtn = document .querySelector (".upload" );uploadBtn.onclick = () => { const xhr = new XMLHttpRequest (); xhr.onload = () => { console .log (xhr.response ); } xhr.responseType = "json" ; xhr.open ("post" , "http://123.207.32.32:1888/02_param/upload" ); const fileEl = document .querySelector (".file" ); const file = fileEl.files [0 ]; const formData = new FormData (); formData.append ("avatar" , file); xhr.send (formData); } uploadBtn.onclick = () => { const fileEl = document .querySelector (".file" ); const file = fileEl.files [0 ]; const formData = new FormData (); formData.append ("avatar" , file); fetch ("http://123.207.32.32:1888/02_param/upload" , { method : "post" , body : formData }).then (res => res.json ()).then (res => console .log (res));
ES6其他规范以及其他补充知识 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 const min = "15" .padStart (2 , "0" );const sec = "6" .padStart (2 , "0" );console .log (min + ":" + sec); let obj = { name : "ear" }const registey = new FinalizationRegistry (value => { console .log ("对象被销毁了" , value); }); registey.register (obj, "obj" ); obj = null ; function foo (message ) { message ??= "默认值" ; console .log (message); } foo ("abc" ); foo (); const message = "my name is ear, ear age is 18" ;const newMessage = message.replace ("ear" , "kobe" );const newMessage2 = message.replaceAll ("ear" , "kobe" );console .log (newMessage); console .log (newMessage2); const obj2 = { name : "ear" , age : 18 , __proto__ : { address : "广安市" } } console .log (obj2.hasOwnProperty ("name" )); console .log (obj2.hasOwnProperty ("address" )); console .log (Object .hasOwn (obj2, "name" )); console .log (Object .hasOwn (obj2, "address" ));
异常处理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 function foo ( ) { console .log ("foo function1" ); throw new Error ("我是错误信息" ); console .log ("foo function2" ); } foo ();
Storage 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
10.DOM
简介
document
元素节点 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 const box1 = document .getElementById ("box1" );const spans = box1.getElementsByTagName ("span" );
文本节点 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 const box1 = document .getElementById ("box1" );console .log (1 , box1.textContent ); console .log (2 , box1.innerText );
属性节点 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 const input = document .getElementsByName ("username" )[0 ];const input2 = document .querySelector ("[name=username]" );console .log (input.disabled ); console .log (input2.className );
事件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <button id ="btn" > 点我一下</button > <button id ="btn2" > 点我一下2</button > <script > const btn = document .getElementById ("btn" ); btn.onclick = function ( ) { alert ("点我了" ); } const btn2 = document .getElementById ("btn2" ); btn2.addEventListener ("click" , function ( ) { alert ("点我了了" ); }); </script >
文档的加载 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 window .onload = function ( ) {} window .addEventListener ("load" , function ( ) {}); document .addEventListener ("DOMContentLoaded" , function ( ) {});
DOM的修改 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 const li = document .createElement ("li" ); li.textContent = "唐僧" ; li.id = "ts" list.appendChild (li); list.insertAdjacentHTML ("beforeend" , "<li id='bgj'>白骨精</li>" ); const swk = document .getElementById ("swk" ); swk.replaceWith (li);
节点的复制 1 2 3 4 5 6 7 const newL1 = l1.cloneNode (true );
11.浏览器知识
回流和重绘 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
defer和async属性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > Document</title > <script defer src ="./js/test.js" > </script > </head > <body > <div > 1111</div > <div > 2222</div > <div > 3333</div > <script > window .addEventListener ("DOMContentLoaded" , () => { console .log ("DOMContentLoaded" ); }); </script > </body > </html >
JS执行原理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34