对象扩展
1.属性名表达式
js定义对象的属性有两种方法。方法一: obj.foo=true;或者obj['foo']=true;是直接用标识符作为属性名。方法二:obj['a'+'bc']=123;用表达式作为属性名,表达式要放在方括号内
2.object.is
ES5比较两个值是否相等只有两个运算符:相等运算符(==)和严格相等运算符(===),他们都有缺点,前者是会自动转数据类型,后者是NaN不等于自身,以及+0=-0。
object提出同值相等算法,用来比较两个值是否严格相等,与===的行为基本一致。
object.is('foo','foo')//true
object.is({},{})//false
object与ES5不同在+0不等于-0,NaN等于自身
object.is(+0,-0)//false
object.is(NaN,NaN)//true
3.object.keys
object.keys可以将对象的每一个属性汇聚成一个数组,然后通过属性去获得属性值
object.values方法就会自动把一个对象里的所有属性值汇聚成一个数组
const obj={
nickname:'张三',
age:18,
hobby:'学习'
}
const values=Object.values(obj);
console.log(values);// ['张三', 18, '学习']
容器
1.Set:集合,类似于数组,但是集合的元素都是唯一的,没有重复的值
set创建有两种方法,第一种是定义一个空的set数据结构,利用set.add()方法添加元素。
const set=new Set();
set.add(1);
set.add(2);
console.log(set);//Set(2) {1, 2}
另外一种创建方式是直接传入数组
const set=new Set([1,2]);
console.log(set);//Set(2) {1, 2}
也可以继续为其添加元素
const set=new Set([1,2]);
set.add(3);
console.log(set);//Set(3) {1, 2, 3}
可以用set.has判断set里是否拥有某一个元素
const set=new Set([1,2]);
set.add(3);
console.log(set.has(1));//true
console.log(set.has(5));//false
使用set.size判断set的长度
const set=new Set([1,2]);
set.add(3);
console.log(set.size);//3
使用set.delete(1)来删除某一个元素
const set=new Set([1,2]);
set.add(3);
set.delete(1);
console.log(set);//Set(2) {2, 3}
使用扩展运算符将set数据结构变成数组
const set=new Set([1,2]);
set.add(3);
set.delete(1);
console.log([...set]);// [2, 3]
也可以用Array.from
const set=new Set([1,2]);
set.add(3);
set.delete(1);
console.log(Array.from(set));// [2, 3]
面试提问:如何对数组去重?
就是用set的不重复性
const arr=[1,2,1,2,3];
console.log([...new Set(arr)]);// [1, 2, 3]
但是要注意NaN和引用类型,
const arr=[1,{},{},3];这里就不会起到去重效果,因为{},{}是引用类型,,引用类型的指针存入它自己的指针和set的指针不一样,而NaN,按理说NaN是不等于NaN的,但是set也会去重。
const arr=[1,NaN,NaN,3];
console.log(arr);//[1,NaN,3]
2.Map:类似与对象,也是键值对的集合,但是键名不仅限于字符串
Map也有两种方法,用Map.set方法来设置key和value,这里注意map的key可以是任何类型,可以是任何的数据类型
(1.)const map=new Map();
map.set('哈哈',12);
map.set(true,988);
map.set(123,'hahaha');
console.log(map);//{'哈哈' => 12, true => 988, 123 => 'hahaha'}
(2.)const map=new Map([['哈哈',12],[true,988],[123,'hahaha']]);//注意这里是二维数组形式
console.log(map);//{'哈哈' => 12, true => 988, 123 => 'hahaha'}
使用map.has方法来判断一个key是否拥有,使用map.get方法来获取value值
const map=new Map([['哈哈',12],[true,988],[123,'hahaha']]);
console.log(map.get('哈哈'));//12
console.log(map.get('哈哈hahah'))//undefined因为上面没有哈哈hahah
用map.delete()删除
const map=new Map([['哈哈',12],[true,988],[123,'hahaha']]);//注意这里是二维数组形式
map.delete('哈哈')
console.log(map);//{true => 988, 123 => 'hahaha'}
默认参数
function showMe(name='兰海鑫',age='22') {
console.log(name,age);
}
showMe('sunshine',22);
就是默认值可以写在实参或者形参括号里
箭头函数
先来写一个普通函数
function sayHello(){
console.log('hello');
}
sayHello()//hello
再写一个普通的箭头函数,箭头函数要通过一个变量去接收,不能以function的形式定义
const sayHello=()=>{
console.log('hello');
}
sayHello()//hello
实参里面写什么就传什么
const sayHello=(meg)=>{
console.log('meg');
}
sayHello('sunshine')//meg
()里面如果只有一个参数括号可以省略,但是如果没参数一个或多个参数不可省略
如果不是console.log是return
const sayHello=(meg)=>{
return `我是${meg}`
}
console.log(sayHello('美女兰海鑫')); //我是美女兰海鑫
如果函数体中只有一个return,则{}可以省略,{}和return也可以一起省略,但是如果多任何一句都不能省略,如果里面只有一个对象又想省略就要加括号
const sayHello=(meg)=>({
m:meg
})
console.log(sayHello('美女兰海鑫')); //{m: '美女兰海鑫'}
this指向
var nickname='sunshine_lan';
const obj={
nickname:'兰海鑫',
sayName:function(){
console.log(this.nickname);//兰海鑫
}
}
obj.sayName()
这个sayName使用obj去调用它的,这时候调用者是object,所以函数里面的this就是指向的调用者,这是普通函数。
如果是箭头函数
var nickname='sunshine_lan';
const obj={
nickname:'兰海鑫',
sayName:()=>{
console.log(this.nickname);//sunshine_lan
}
}
obj.sayName()
因为箭头函数是没有自己的this的,this只能指向外界,外界就是全局就是window下的nickname,而且是定的,不像普通函数一样调用者调用这个函数之后this就指向这个调用者,箭头函数不会的。
函数体内的this对象就是定义时所在的对象,而不是使用时所在的对象。this对象的指向是可变的,但是在箭头函数中是固定的。
注意:1.箭头函数不能当作构造函数,因为在创建实例时是需要this指向的,但是箭头函数没有this,所以不能当作构造函数来使用,不可以使用new命令。
const Person=()=>{};
const person=new Person{};
这样 会报错
2.箭头函数没有argument对象,用扩展运算符。
登录操作正常流程:先请求登录的接口,然后拿着登录接口返回的结果再去请求用户的信息接口
可选链和空位运算符
1.可选链 ?.:可选链可以用在数组,函数和对象身上
数组:const first=list?.[0]先去判断可选链前面的list是否存在,如果不存在直接返回undefined,如果存在就会去找它的0索引值这一项
对象:const obj={
cat:{
name:'张三',
}
}
想在这个对象里找有没有dog,就用const dog=obj?.dog?.name,先去找可选链前面的东西是否存在,如果存在就继续往下找dog,如果还存在就再继续往下找name,如果中间哪一环不存在就直接返回undefined。
函数:const fn=null,判断这个函数有没有值,如果有值就直接执行。就用fn?.(),先判断fn函数是否存在,如果存在就执行
2.空位合并运算符??
const a=0||'张三';
const b=''||'张三';
const c=false||'张三';
const d=undefined||'张三';
const e=null||'张三';
代码中||或运算符前面如果是假的就直接输出后面的数了,在这一串代码如果想输出0或者''或者false就要用空位运算符,
const a=0??'张三';//0
const b=''??'张三';//''
const c=false??'张三';//false
const d=undefined??'张三';//张三
const e=null??'张三';//张三
console.log(a,b,c,d,e);
在这一串代码就能输出0或者''或者false本身了,因为空位合并运算符只会把undefined和null当成假值,就是只有前面是undefined和null才会被当成假值,假值才回去返回后面的东西,除了这两个之外的值都会被判断成真值,这就是空位合并运算符与或运算符的区别
reduce
1.累加
const arr=[1,2,3,4,5];
let num=0;
for (let i = 0;i<=arr.length;i++) {
num=num+i;
}
console.log(num);
现在可以直接用reduse,reduse接受两个参数,第一个参数是一个函数,函数又接收形参和实参,第二个参数是一个初始值,可以选择传或者不传,如果传了初始值,那么这个初始值就会被当成第一次循环时候的pre,如果不传初始值那第一次循环的pre就是第一项。
const arr=[1,2,3,4,5];
console.log(arr.reduce((pre,next)=>{
return pre+next;//15
}));
因为没有传初始值,所以第一次循环的pre就是数组的第一项,next就是数组的第二项,1+2=3,把3给return,下一次循环时就是pre上一次循环的return的值3,3+3=6,把6给return,6又变成下一次循环的pre。
如果要传入初始值就这样,假如传入的初始值是0
const arr=[1,2,3,4,5];
console.log(arr.reduce((pre,next)=>{
return pre+next;//15
},0));
这时第一次循环的pre就是0,第一次循环的next就是数组的第一项1。
如果想再加10可以这样
const arr=[1,2,3,4,5];
console.log(arr.reduce((pre,next)=>{
return pre+next;//15
},10));//25
这时候相当于数组[10,1,2,3,4,5]累加
2.去重
求幂运算符
//3*3
const num=3*3;
console.log(num);//9
//3*3*3
const num1=3*3*3;
console.log(num1);//27
可以这么写但是如果有很多的需求就不能这样,也可以用Math.pow(x,y)要×几次写在y里
const num =Math.pow(3,2);
console.log(num);
ES6可以直接用**
const num =3**5;
console.log(num);//243
const num1 =3**4;
console.log(num1);//81
**后面就是乘几次
includes方法
includes方法既可以被字符串使用也可以被数组使用,作用是传入一个元素并且判断调用者身上又没有这个元素,如果拥有返回一个true,如果没有返回false。
const str='我是星星';
const bol=str.includes('星');
console.log(bol);//true
const bol1=str.includes('五');
console.log(bol1);//false
数组使用方法也是定义一个变量来接收
const arr=[1,2,3,4,5];
const bol=arr.includes(3);
console.log(bol);
ES6之前也有一个方法也是判断调用者身上有没有这个元素--indexOf,indexOf是通过寻找索引的方法。
const arr=[1,2,3,4,5];
const index=arr.indexOf(3);
console.log(index);//2
const index1=arr.indexOf(5);
console.log(index1);//4
const index2=arr.indexOf(6);
console.log(index2);//-1 找不到就返回-1
面试题目:indexOf和includes的区别是:indexOf判断不了NaN,二includes可以
const arr=[1,2,3,4,NaN];
const index=arr.indexOf(NaN);
console.log(index);//-1
const bol=arr.includes(NaN);
console.log(bol);//true