1、对象中属性和方法的简写
- 属性的简写
简写前 | 简写后 |
---|---|
uname: uname | uname |
age: age | age |
- 方法的简写
简写前 | 简写后 |
---|---|
fn:function(){console.log(“fn…”)} | fn(){console.log(“fn…”)} |
2、数组的解构和对象的解构
- 解构的目的:从数组或对象中快速获取数据
1、数组的解构赋值:
let names = ["aa","bb","cc"];
let [x,y,z] = names;
let [a,b,c] = ["red","green","yellow"];
- 只解构部分元素
let [a,,c] = ["red","green","yellow"];
- 将后面的元素放到一个新的数组中
let [item1,...newName] = ["xh","xm","mary","tom","jerry"];
console.log(item1); //xh
console.log(newName); //[ 'xm', 'mary', 'tom', 'jerry' ]
- 若不给item4赋默认值,它的值就是und
let [item1,item2,item3,item4 = "tom"] = ["xh","xm","mary"];
2、对象的解构赋值
let obj = { name:"tom", age:18, height:1.88 }
//对象中是什么键,解构出来也应该是什么键
let { name, age, height } = obj;
- 解构部分属性:
let obj = { name:"tom", age:18, height:1.88 }
let { age } = obj;
- 给解构出来的属性指定别名:
let obj = { name:"tom", age:18, height:1.88 }
let { age:newAge } = obj;
console.log(newAge); //18
- 调用函数时解构
let obj = { name:"tom", age:18, height:1.88 }
function foo({name,age,height}){
console.log(name,age,height)
}
foo(obj)
3、模板字符串
字符串拼接→模板字符串
**注意:**模板字符串中的两点不是单引号,是tab键上面的点
let uname = "tom";
let age = 18;
let height = 1.88;
//字符串拼接
console.log(uname + "今年" + age + "了,身高是" + height);
//模板字符串
console.log(`${uname}今年${age}了,身高是${height}`);
//在${}中可以进行简单的运算
console.log(`${uname}今年${age+2}了,身高是${height}`);
- 在模板字符串中调用函数:
function doubleAge(age){
return age*2;
}
console.log(doubleAge(10));
let info = `double age is ${doubleAge(20)}`
console.log(info);
- 其他
let name = "xh";
let age = 18;
function foo(a,b,c){
console.log(a,b,c,"---------");
}
//第一个参数是模板字符串整体字符串,被切成多块放在一个数组中
//第二、三...个参数是模板字符串中,第1、2...个${}中的内容
foo`Hello${name}OK${age}`; //[ 'Hello', 'OK', '' ] xh 18 ---------
4、函数的默认参数
ES6之前,编写的函数没有默认参数
function foo(m,n){
//若没有指定实参,m和n的值是und
console.log(m,n); //undefined undefined
}
foo();
- 给函数的参数指定默认值
function foo(m="hello",n="world"){
console.log(m,n); //hello world
}
foo();
- 对象的解构和默认值配合使用
function foo({name,age} = {name:"tom",age:20}){
console.log(name,age);
}
foo(); //tom 20
foo({name:"mary",age:16}) //mary 16
- 另一种写法:
function foo({name="tom",age=20} = {}){
console.log(name,age);
}
foo(); //tom 20
foo({name:"mary",age:16}) //mary 16
- 有默认值的形参放到最后面
function foo(x, y = 666, z){
console.log(x,y,z);
}
foo(10,20,30); //10 20 30
foo(10,20); //10 20 undefined
foo(10); //10 666 undefined
- 函数中的length属性表示形参的个数:
function foo(x,y,z){
console.log(x,y,z);
}
console.log(foo.length); //3
5、函数的剩余参数
ES6之前,伪数组arguments保存了实参数据,其本质是一个对象,在ES6中,使用了剩余参数args来代表arguments,args是一个真正的数组。
function foo(...args){
console.log(arguments); //[Arguments] { '0': 10, '1': 20, '2': 30, '3': 40 }
console.log(args); //[ 10, 20, 30, 40 ]
}
foo(10,20,30,40);
形参+args(args只能放在最后面)
function foo(num1,num2,...args){
console.log(num1,num2); //10 20
console.log(args); //[ 30, 40 ]
}
foo(10,20,30,40);
6、箭头函数
- 箭头函数中没有this
- 箭头函数中没有arguments
- 箭头函数没有原型对象,不能new
7、展开运算符
语法:… 展开运算符,底层使用的是迭代器,对象不是可迭代对象,对象不能展开
使用场景:
- 在函数调用时使用
- 在数组构造时使用
- 在构建对象字面量时
let names = ["tom","lili","mary","jerry"];
let obj = { name:"tom", age:18};
let item = "xxxx";
//调用函数时,使用展开运算符,一个个取出来
function foo(x,y,z){
console.log(x,y,z);
}
foo(...names); //tom lili mary
//将字符串展开
foo(...item); //x x x
//对对象使用展开运算符需在外面包一个对象
let res = {...obj, address: "bj", ...names};
console.log(res);
浅copy
//浅copy,copy的是地址
let info = {name:"tom",age:18};
let ok = info; //info和ok指向同一个堆
展开运算符实现的是浅copy
let info = {name:"tom",age:18,friend:{name:"mary",age:20}};
let res = {...info};
info.friend.name = "mary123";
console.log(res.friend.name);
8、数值表示
ES6之前,数值可以用十进制、二进制、八进制、十六进制表示
ES6+中数字过长可以使用_连接符(如:100_000_000)
9、Symbol
ES6中新增的一个基本数据类型
ES6之前,对象的属性名都是字符串,容易造成属性名冲突,Symbol用来生成一个独一无二的值,
ES6之后,对象的属性名可以是字符串,也可以是Symbol值。
Symbol可以创建多次,每次都是独一无二的,在创建时,可以传入一个description。
10、Set集合
ES6之前只有数组和对象可以存储大量的数据
ES6中,增加了两种数据解构:Set、Map
以及这两种数据结构的另外两种形式:WeakSet、WeakMap
Set类似数组,但不能存储重复的元素。
通过Set构造器就可以创建set容器,没有字面量的创建形式。
WeakSet
WeakSet中只能存储对象,不能存储基本数据类型,不能遍历,里面存储的是弱引用,如果没有别人对它引用,GC就会进行回收。
GC回收不了强引用
11、Map集合
WeakMap
12、Array Includes
判断一个数组中是否包含了某个元素
indexOf→includes
indexOf:如果没有,返回-1,如果有则返回对应元素的下标
includes:如果包含返回true,否则返回false
let names = ["tom","mary","jerry",NaN];
if(names.indexOf("jerry") !== -1){
console.log("包含了jerry");
}
//NaN判断不出来
if(names.indexOf(NaN) !== -1){
console.log("包含了NaN")
}
//ES7 ES2016
if(names.includes("tom")){
console.log("包含了tom");
}
if(names.includes(NaN)){
console.log("包含了NaN");
}
13、指数表示
Math.pow→**
14、获取对象中的key和value
let obj = {name:"tom",age:18}
//得到对象中所有的key并放到一个数组中
console.log(Object.keys(obj)); //[ 'name', 'age' ]
//得到对象中所有的values并放到一个数组中
console.log(Object.values(obj)); //[ 'tom', 18 ]
entries获取key和value并放在二维数组中
let obj = {name:"tom",age:18}
console.log(Object.entries(obj)); //[ [ 'name', 'tom' ], [ 'age', 18 ] ]
15、String Padding
padStart:从字符串开始补全长度
let str = "hello world";
console.log(str.padStart(20,"*")); //*********hello world
padEnd:从字符串最后补全长度
let str = "hello world";
console.log(str.padEnd(20,"-")); //hello world---------
案例:
let cardNumber = "758473839204586784924252452";
console.log(cardNumber.slice(-4)); //截取后四位 2452
//***********************2452
console.log(cardNumber.slice(-4).padStart(cardNumber.length,"*"));
16、ES8,最后形参可以加逗号
function foo(a,b,c,){
console.log(a,b,c);
}
foo(1,2,3)
17、Class定义类
使用class定义类
class Person{}
//另一种写法:let Person = class{}
let p = new Person();
console.log(p); //Person {}
通过类创建出来的对象和通过构造器创建出来的对象特性基本一样,也有prototype。
赋值私有属性和公有属性
constructor() 方法是一种特殊的方法,用于创建和初始化在类中创建的对象,一个类中只有一个constructor。
1、内部创建一个对象nm = {}
2、将Person的原型prototype赋值给创建出来的对象 nm._proto_ = Person.prototype
3、将对象赋值给this 将this指向对象 new绑定 this = nm;
4、执行constructor中的代码
5、返回创建出来的对象 return nm
私有属性:
class Person{
constructor(name,age){
this.name = name;
this.age = age;
}
}
let p = new Person("tom",18); //私有属性
公有属性:
class Person{
constructor(name,age){
this.name = name;
this.age = age;
}
//running是原型对象上的属性
running(){
console.log(this.name + "running");
}
}
类中的设置器和访问器:
class Person{
constructor(name,age){
this.name = name;
this.age = age;
this._address = 'bj'
}
//访问器
get address(){
console.log("getter调用了~");
//getter返回什么,address属性就是什么
return this._address;
}
//设置器
set address(value){
this._address = value;
}
}
let p = new Person("tom",18); //new一个对象
console.log(p.address); //自动调用上面的get address(){}
p.address = "gz" //自动调用上面的set address(){}
console.log(p.address); //自动调用上面的get address(){}
静态属性:
class Person{
//私有属性
constructor(name,age){
this.name = name;
this.age = age;
}
//公有属性
running(){
console.log(this.name + " running...");
}
//静态属性 只能通过类名来访问
static eating(){
console.log("eating...");
}
}
Person.eating(); //eating...
继承extends
class Person{
constructor(name,age){
this.name = name;
this.age = age;
}
running(){
console.log(this.name + "running...");
}
static eating(){
console.log("eating...");
}
}
//extends继承
class Student extends Person{
constructor(name,age,sno){
super(name,age); //super()表示调用Person的constructor
this.sno = sno;
}
}
let stu = new Student("mary",20,083948765);
console.log(stu.name);
console.log(stu.age);
stu.running(); //maryrunning... Student继承了Person的公有属性
Student.eating(); //eating... Student继承了Person的静态属性
父类的公有属性,子类可以重写
class Person{
constructor(name,age){
this.name = name;
this.age = age;
}
running(){
console.log(this.name + "running...");
}
}
//extends继承
class Student extends Person{
constructor(name,age,sno){
super(name,age); //super()表示调用Person的constructor
this.sno = sno;
}
running(){
super.running(); //调用父类的running
console.log("Student running...");
}
}
let stu = new Student("mary",20,083948765);
stu.running(); //Student继承了Person的公有属性
//maryrunning...
//Student running...
自己写的类可以继承JS中的内置的类
class MyArray extends Array{
//重写
push(){
console.log("......");
}
}
//创建对象
let marr = new MyArray();
marr.push(1); //......
marr.push(2); //......
console.log(marr); //MyArray(0) []
18、flat和flatMap
flat可以将数组降维,没有写参数则降1维
let nums = [[30,18],[40,20,[88,44]]];
let newNums = nums.flat(2);
console.log(newNums); //[ 30, 18, 40, 20, 88, 44 ]
map可对数组中的元素进行加工处理
let nums1 = [10,20,30];
let newNums1 = nums1.map(item=>{
return item*2
})
console.log(newNums1); //[ 20, 40, 60 ]
flatmap为高阶函数,具有遍历功能,flatmap兼具flat与map的功能
let nums = [10,20,30,[40]] //二维
let newNums = nums.flatMap(item=>{
return item*2;
})
console.log(newNums); //降维+加工[ 20, 40, 60, 80 ]
19、fromEntries(ES10)
Object.entries()方法返回一个给定对象自身可枚举属性的键值对数组
let obj = {
name: "tom",
age: 18
}
console.log(Object.keys(obj)); //[ 'name', 'age' ]
console.log(Object.values(obj)); //[ 'tom', 18 ]
console.log(Object.entries(obj)); //[ [ 'name', 'tom' ], [ 'age', 18 ] ]
fromEntries可将entries还原成对象
let obj = {
name: "tom",
age: 18
}
entries = Object.entries(obj);
let newObj = Object.fromEntries(entries);
console.log(newObj);
20、trim
trim去掉字符串两边的空格(不包括字符串中间的空格)
trimStart去掉字符串前面的空格
trimEnd去掉字符串后面的空格
let msg = " hello world "
console.log(msg.trim()); //hello world
21、ES11(部分)
1、BigInt
ES11引入了新的数据类型BidInt
JS中的基本数据类型有7个:number、string、Boolean、null、und、symbol、bigint
要表示BigInt,只需要在数字的后面加上n即可
console.log(typeof(10n)); //bigint
也可以使用构造函数来构造bigInt:
const bigInt = BigInt("10");
console.log(typeof(bigInt)); //bigint
console.log(bigInt); //10n
注意: Number与BigInt不能相运算,会报TypeError异常,可以进行类型转化
2、??操作符
与||的区别:当somebody.age为0时:
const yourAge = somebody.age || 18 //18
const yourAge = somebody.age ?? 18 //0
3、?.操作符
可选运算符,若某个属性没有值,不会报错,会输出undefined
let obj = {}
console.log(obj?.friend?.firlFriend?.name); //undefined