对象解构 当存在变量名与对象名重复的情况时,可以在解构中重新定义一个变量来读取对象里的内容
1 2 3 4 const obj = { name : "abc" };const name = "aaa" ;const { name : newName } = obj;console .log(newName);
也可以直接设置默认值
1 2 3 4 5 const obj = {};const { name = "abc" } = obj; const name = "aaa" ;const { name : newName2 = "def" } = obj;
数组解构 可以通过变量来获取不同位置的值从而生成新的数组
1 2 3 const arr = [1 , 2 , 3 ];const [_a, ...rest] = arr;console .log(_a, rest);
解构数组的同时可以设置新的变量值
1 2 const [q, w, e, r = 4 ] = arr;console .log(q, w, e, r);
实战中可以通过解构的方式去获取 split 里的值
1 2 3 const name = "Jab-Fury" ;const [, lastName] = name.split("-" );console .log(lastName);
for-of 在遍历过程中,可以通过 break 来跳出循环
1 2 3 4 5 6 7 const num = [1 , 2 , 3 , 4 , 5 ];for (let i of num) { if (i > 3 ) { break ; } console .log(i); }
for-of 也能遍历 Map()类型的数据,遍历出的每一项是其键值,每项键值是数组类型,因此可以结合数组的结构分别获取到每项的键和值。
1 2 3 4 5 6 7 8 9 const m = new Map (); m.set("a" , 123 ); m.set("b" , 456 );for (let i of m) { console .log(i); }for (let [key, value] of m) { console .log(key, value); }
const const 定义的只读范围是是否能够改变内存地址,引用类型的变量是不会改变内存地址的,因此可以赋值
1 2 3 const obj = {}; obj.name = "abc" ;console .log(obj);
Object.is() Object.is()方法不会强制转换两边的值,”==”和”===”会将两个不是同一类型的值进行装换后再对比
1 2 3 4 5 6 7 console .log(NaN == NaN ); console .log(NaN === NaN ); console .log(Object .is(NaN , NaN )); console .log(+0 == -0 ); console .log(+0 === -0 ); console .log(Object .is(+0 , -0 ));
Symbal for 方法里面维护的都是字符串的值,如果传入的值不为字符串,for 方法也会将其转换为字符串
1 2 3 4 5 6 7 8 9 const s1 = Symbol .for("aaa" );const s2 = Symbol .for("aaa" );console .log(s1 === s2); const s3 = Symbol .for("true" );const s4 = Symbol .for(true );console .log(s3); console .log(s4); console .log(s3 === s4);
传统方法获取不到对象中定义的 Symbol 方法,只能通过 getOwnPropertySymbols()拿到对象中定义的 Symbol 属性 (只能获取到全是 symbol 类型的属性名)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 const o1 = { [Symbol ("bbb" )]: "symbol value" , name : "aaa" , age : 23 , };for (let i in o1) { console .log(i); }console .log(Object .keys(o1)); console .log(JSON .stringify(o1)); console .log(Object .getOwnPropertySymbols(o1));
模板字符串 模板字符串可以用一个方法控制,并接受参数,第一个参数会返回所有字符串的一个数组,以每个${}变量处截取的
1 2 3 4 5 6 7 8 9 10 11 12 const name = "abc" ;const gender = true ;function myTagFunc (strings, name, gender ) { console .log(strings); return ( strings[0 ] + name.toUpperCase() + strings[1 ] + (gender ? "man" : "woman" ) ); }const result = myTagFunc`hello my name is ${name} , I'm a ${gender} ` ;console .log(result);
class 与普通 function 的区别 1.声明不能提升,会直接报错(类似 const、let); 2.class 所有方法都不可枚举 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 Bar ( ) { this .bar = 42 ; } Bar.answer = function ( ) { return 42 ; }; Bar.prototype.print = function ( ) { console .log(this .bar); };const barKeys = Object .keys(Bar); const barProtoKeys = Object .keys(Bar.prototype); class Foo { constructor ( ) { this .foo = 42 ; } static answer ( ) { return 42 ; } print ( ) { console .log(this .foo); } }const fooKeys = Object .keys(Foo); const fooProtoKeys = Object .keys(Foo.prototype);
3.class 里面所有的方法(包括静态、实例方法)都没有原型对象 prototype,所以不能用 new 来调用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 function Bar ( ) { this .bar = 42 ; } Bar.prototype.print = function ( ) { console .log(this .bar); };const bar = new Bar();const barPrint = new bar.print(); class Foo { constructor ( ) { this .foo = 42 ; } print ( ) { console .log(this .foo); } }const foo = new Foo();const fooPrint = new foo.print();
4.class 必须使用 new 来调用 1 2 3 4 5 6 7 8 9 10 11 function Bar ( ) { this .bar = 42 ; }const bar = Bar(); class Foo { constructor ( ) { this .foo = 42 ; } }const foo = Foo();
4.class 内部无法重写类名 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 function Bar ( ) { Bar = "Baz" ; this .bar = 42 ; }const bar = new Bar();class Foo { constructor ( ) { this .foo = 42 ; Foo = "Fol" ; } }const foo = new Foo(); Foo = "Fol" ;