2.语法扩展

  一、剩余参数与展开运算符

1.剩余参数

剩余参数永远是个数组,即使没有值,也是空数组

const add=(x,y,z,...args)=>{};

1.1注意事项

a.箭头函数的剩余参数

箭头函数的参数部分即使只有一个剩余参数,也不能省略圆括号

b.使用剩余参数替代arguments获取实际参数

const add=function(){
    console.log(arguments);
};
add(1,2)
//箭头函数没有arguments
//arguments是类数组,剩余参数是数组
const ada=(...args)=>{
    console.log(args);
}
ada(1,2)

c.剩余参数的位置

剩余参数只能是最后一个参数,之后不能再有其他参数,否则会报错

1.2剩余参数的应用

a.

const add=(...args)=>{
            let sum=0;
            for(let i=0;i<args.length;i++){
                sum+=args[i];
            }
            return sum;
        }
        console.log(add(1,2,3))

b.与解构赋值结合使用

//剩余参数不一定非要作为函数参数使用
const [num,...args]=[1,2,3,4]
console.log(num,args)

//
const {x,y,...z}={a:3,x:1,y:2,b:4}
console.log(x,y,z)

2.数组的展开运算符(...)

2.1数组展开运算符的基本用法

console.log(Math.min(1,2,3))
//等价于
console.log(Math.min(...[1,2,3]))

2.2区分剩余参数和展开运算符

//剩余参数
1,2,3->[1,2,3]
//展开运算符
[1,2,3]->1,2,3

const add=(...args)=>{
    console.log(args);
    console.log(...args);
};
add(1,2,3)

2.3数组展开运算符的运用

2.3.1复制

//复制
const a=[1,2]
const b=a
a[0]=3
console.log(b)
//b数组跟着a数组的变化而变化

const c=[...a]
a[0]=4
console.log(c)
console.log(a)

2.3.2合并数组

//合并数组
const a=[1,2]
const b=[1,5,3,7]
const c=[..a,..b]
const d=[...c,10,15,..a]

2.3.3字符串转换为数组

//字符串可以按照数组的形式转换
console.log(..."Alex")
//等价于
console.log("A","l","e","x")
console.log([..."Alex"])

2.3.4类数组转化为数组(arguments,nodelist)

2.4对象的展开运算符

2.4.1基本用法:

a.对象不能直接展开,必须在{}中展开

b.对象的展开:把属性罗列出来,用逗号隔开,放到一个{}中,构成新对象

c.合并对象:新对象拥有全部属性,相同属性,后者覆盖前者

2.4.2注意事项

a.空对象的展开,则没有任何效果

b.非对象的展开:如果展开的不是对象,则会自动将其转为对象,在将属性罗列出来;如果展开运算符后面是字符串,他会自动转成一个类似数组的对象,因此返回的不是空对象

c.对象中对象属性的展开:不会展开对象中的对象属性(合并:后面的覆盖前面的,而不是和前面的合并(相同属性覆盖,不同属性留下))

const apple={
    feature:{
        taste:"甜"    
    }
};
const pen={
    feature:{
        color:"黑色",
        shape:"圆柱形"
    },
    use:"写字"
}
console.log({...apple})//不会展开对象中的对象属性

console.log({...apple,...pen})//后面的覆盖前面的,不是合并

//result:
//{feature:{
        color:"黑色",
        shape:"圆柱形"
    },
    use:"写字"
}

2.4.3对象展开运算符的运用

a.复制对象

const b={x:1,y:2}
const a={...b}

b.用户参数和默认参数

二、Set和Map数据结构

1.Set数据结构

1.1Set是一系列无序、没有重复值的数据集合(Set没有下标去标示每一个值,所以Set是无序的),数组是有序集合。

1.2Set中不能有重复的成员

const s=new Set([1,2,1])

s.add(3).add(5).add(6)
console.log(s)

1.3Set的实例方法和属性

//一、方法
//1.add
const s=new Set();
s.add(1).add(2)

//2.has:检查集合中是否存在这个成员
console.log(s.has(1))

//3.delete:删除指定的成员,当删除不存在的成员时,什么都不会发生,也不会报错
s.delete(1)

//clear:清除集合中的所有成员
s.clear();

//forEach:遍历每个成员(按照成员添加进集合的顺序遍历)
s.forEach(function(value,key,set){
    //Set中value=key
    console.log(value,key,set===s)
    console.log(this)
},document)

//二、属性
//size
console.log(s.size)

1.4Set的注意事项

1.4.1Set对重复的判断基本遵循严格相等(===),但是对于NaN的判断与===不同,Set中的NaN等于NaN

1.4.2什么时候使用Set

a.数组或字符串去重时

b.不需要通过下标访问,只需要遍历时

c.为了使用Set提供的方法和属性时(add delete clear has forEach size 等)

1.5Set的应用

1.5.1数组去重

[1, 2, 1];
const s = new Set([1, 2, 1]);
console.log(s);
s.forEach

console.log(...s);
console.log([...s]);
console.log([...new Set([1, 2, 1])]);

1.5.2字符串去重

'abbacbd';
const s = new Set('abbacbd');
console.log([...s].join(''));
console.log(s);
console.log([...new Set('abbacbd')].join(''));

1.5.3存放DOM元素

console.log(document.querySelectorAll('p'));
      for()
      const s = new Set(document.querySelectorAll('p'));
      console.log(s);
      s.forEach(function (elem) {
        // console.log(elem);
        elem.style.color = 'red';
        elem.style.backgroundColor = 'yellow';
      });

2.Map数据结构

1.1Map和对象都是键值对的集合

const m=new Map()
m.set('name','alex')
console.log(m)

1.2Map和对象的区别

1.2.1:对象一般用字符串当作键

const obj={
    name:'alex',
    age:18,
}
//由于name和age是正确的标识符,所以可以取掉引号

1.2.2:Map的键的类型

基本数据类型:数字、字符串、布尔值、undefined、null

引用数据类型:对象([]、{}、函数、Set、Map等)这两种数据类型都可以作为Map的键。

1.3Map的注意事项

1.3.1判断键名是否相同的方式:基本遵循严格相等(===),列外就是NaN,Map中NaN也是等于NaN

console.log(NaN===NaN)
const m=new Map()
m.set(NaN,1).set(NaN,2)
console.log(m)
console.log(new Map([
    ['name','alex'],
    ['age',18]
]))

1.3.2什么时候使用Map:如果只是需要key->value的结构,或者需要字符串以外的值做键;只有模拟现实世界的实体时,才使用对象。

1.4Map的应用

const m=new Map([
    p1,{
        color:'red',
        backgroundColor:'yellow',
        fontSize:'40px'
    },
    p2,{
        color:'green',
        backgroundColor:'blue',
        fontSize:'40px'
    },
    p3,{
        color:'pin',
        backgroundColor:'white',
        fontSize:'40px'
    },
]);
m.forEach((propObj,elem)=>{
    for(const p in propObj){
        elem.style[p]=propObj[p]
    }
})

1.5for...in方法

1.5.1定义:for...in语句用于遍历数组或对象属性,也就是说,for...in循环中的代码每执行一次,就会对数组的索引(或对象的属性)进行一次操作。

1.5.2语法:

(1)variable:每次循环时,variable会被赋值为不同的属性名。

(2)object:可迭代的对象,即:可遍历的对象。

for (variable in object){

}

1.5.3实例

(1)遍历数组

const arr=['a','b','c','d']
for (const key in arr){
    console.log('索引key:',key)
    console.log("元素arr[key]:",arr[key])
}

(2)遍历对象

const obj={
    name:'alex',
    age:18,
    sex:'male'
}
for (const key in obj){
    console.log(key)
    console.log(obj[key])
}

遍历对象时,key 表示属性名;遍历数组时,key表示索引。

1.5.4区分forEach和for...in

(1)forEach和for...in都可以遍历数组

(2)for...in可以遍历对象,forEach不可以

(3)for...in支持break和continue关键字,forEach不支持。以break关键字为例:

a)for...in方法:

const obj={
    name:'alex',
    age:18,
    sex:'female'
}
for(const item in obj){
    console.log(item)
    if(item=='name'){
        break;
    }
}

b)forEach方法

const arr=['a','b','c','d']
arr.forEach(elem=>{
    console.log(elem)
    if(elem=='b'){
        break
    }
})
//打印结果报错

三、遍历器与for...of

1.Iterator的作用:遍历器(迭代器)

2.使用Iterator

const it=[1,2][Symbol.iterator]();
console.log(it.next());//{value:1,done:false}
console.log(it.next());//{value:2,done:false}
console.log(it.next());//{value:undefined,done:true}

//it:可遍历对象
//Symbol.iterator:可遍历对象的生成方法

3.什么是Iterator

Symbol.iterator(可遍历对象的生成方法) ->(可遍历对象)。

4.为什么需要Iterator遍历器

(1)遍历数组:for循环和forEach方法

(2)遍历对象:for in循环

Iterator遍历器是一个统一的遍历方法

5.for...of的用法

const arr=[1,2,3]
const it=arr[Symbol.iterator]()
let next=it.next();
while(!next.done){
    console.log(next.value);
    next=it.next();
    console.log(next)
}

//for...of就是Iterator封装好之后的
for(const item of arr){
    console.log(item)
}
//for...of循环只会遍历出那些done为false时,对应的value值

5.1:for...of 可以与break和continue一起使用

const arr=[1,2,3]
for (const item of arr){
    if(item===2){
        break;
        //continue
    }
}

5.2:在for...of中取得数组的索引

const arr[1,2,3]
console.log(arr.keys());
//keys()得到的是索引的可遍历对象,可以遍历出索引值
for(const key of arr.keys()){
    console.log(key)
}
console.log(arr.values())
//values()得到的是值是可遍历对象,可以遍历出值
for(const value of arr.values()){
    console.log(value)
}

//entries()得到的是索引+值组成的数组的可遍历对象
for(const key entrie arr.entries()){
    console.log(entrie)
}

6.原生可遍历和非原生可遍历

6.1:什么是可遍历:

只要有Symbol.iterator方法,并且这个方法可以生成可遍历对象,就是可遍历的;只要可遍历,就可以使用for...of循环来统一遍历

6.2:原生可遍历的:数组、字符串、Set、Map、arguments、NodeList

//数组
for(const item of [1,2,3]){
    console.log(item)
}
//字符串
for(const item of 'hi'){
    console.log(item)
}
//Set
for(const item of new Set([1,2])){
    console.log(item)
}
//Map
for (const item of new Map([
      ['name', 'alex'],
      ['age', 18]
    ])) {
      console.log(item)
    }
//arguments
for(const elem of document.querySelectorAll('p')){
    console.log(elem);
    elem.style.color='red'
}
//NodeList

6.3:非原生可遍历的:

一般的对象:

const person={sex:'male',age:18};
console.log(person[Symbol.iterator]())
//打印结果报错,因为一般的对象是没有Symbol.iterstor方法的
//没有Symbol.iterator方法,我们给他添加一个这个方法

person[Symbol.iterator]=()=>{
    let inedx=0;
    return{
        next(){
            index++;
            if(index===1){
                return{
                    value:person.age,
                    done:false
                };
            }else if(index===2){
                return{
                    value:person.sex,
                    done:false
                };
            }else{
                return{
                    done:true
                }
            }
        }
    }
}


//有 length 和索引属性的对象
    const obj = {
      '0': 'alex',
      '1': 'male',
      length: 2
    };

    obj[Symbol.iterator] = Array.prototype[Symbol.iterator];

    obj[Symbol.iterator] = () => {
      let index = 0;

      return {
        next() {
          let value, done;
          if (index < obj.length) {
            value = obj[index];
            done = false;
          } else {
            value = undefined;
            done = true;
          }

          index++;

          return {
            value,
            done
          };
        }
      };
    };
    for (const item of obj) {
      console.log(item);
    }

四、ES6的新增方法

1.includes():

判断字符串中是否含有某些字符(返回的布尔值),或判断数组中是否含有某个成员

console.log('abc'.includes('a'))//true
console.log('abc'.includes('ac'))//false
//第二个参数:表示开始搜素的位置,默认是0
console.log('abc'.includes('a',0))
console.log([1,2,3].includes(2));
//基本遵循严格相等(===),但是对于NaN的判断与===不同,includes认为NaN===NaN
console.log(NaN===NaN)
//结果:false
console.log([1,2,3,NaN].includes(NaN))
//结果:true

1.1应用

//https://www.imooc.com/course/list
//https://www.imooc.com/course/list?c=fe&sort=pop&name=value

let url='https://www.imooc.com/course/list';
const addURLParam=(url,name,value)=>{
    url+=url.includes('?')?'&':'?';
    url+=`${name}=${value}`;
    return url;
};
url=addURLParam(url,'c','fe');
console.log(url);
url=addURLParam(url,'sort','pop')
console.log(url)

//includes在数组中的应用:去重
const arr=[];
for (const item of [1,2,1]){
    if(!arr.includes(item)){
        arr.push(item);
    }
}
console.log(arr)

2.padStart()和padEnd():补全字符串长度

console.log('x'.padStart(5,'ab'))
//5:为补全之后的长度,结果为ababx
console.log('x'.padEnd(4,'ab'))
//结果:xaba

2.1注意事项

用来补全的字符串与原字符串长度之和超过了最大长度,截取超出位数的补全字符串,原字符不动。

console.log('xxx'.padStart(2,'ab'))
//结果为:xxx

用来补全的字符串与原字符串长度之和超过了最大长度,截取超出位数的补全字符串,原字符串不动。

console.log('abc'.padStart(10,'0123456789'))
//结果:0123465abc

如果省略第二个参数,默认用空格补全长度。

3.trimStart()【trimLeft()】和trimEnd()【trmiRight()】:

清除首或尾的空格,中间的空格不会清除。trim():清除首尾的空格。

4.Array,.from():

将其他数据类型转换成数组。

console.log(Array.from('arr'));
//结果:['a','r','r']

4.1:那些可以通过Array.from()转换成数组

(1)所有可遍历的:数组、字符串、Set、Map、NodeList、arguments

console.log(Array.from(new Set([1,2,1])))
//结果:[1,2]
console.log([...new Set([1,2,1])])
//结果:[1,2]

(2)拥有属性的任意对象

const obj={
    '0':'a',
    '1':'b',
    length:1
};
console.log(Array.from(obj))
//结果:['a']
const obj={
    '0':'a',
    '1':'b',
    length:2
};
console.log(Array.from(obj))
//结果:['a','b']
const obj={
    '0':'a',
    '1':'b',
    name:'alex',
    length:3
};
console.log(Array.from(obj))
//结果:['a','b',undefined]

4.2:第二个参数:作用类似于数组的Map方法,用来对买个元素进行处理,经处理后的值放入返回的数组。

console.log([1,2].map(value=>value*2))
//结果:[2,4]

console.log(Array.from('12',value=>value*2))
console.log(Array.from(''12').map(value=>value*2))
//结果:[2,4]

4.3:第三个参数:修改它的this指向

Array.from('12',value=>{
    console.log(this);
    },document)
//document为第三个参数,用来修改它的this指向,但在这并不能修改成功,因为用了箭头函数,箭头函数
//在声明的时候就确定好了this指向,要改变它的this指向用其他函数。
Array.from('12',function(){
    console.log(this)
    },doucment)
//this指向改为了document

5.find()

【找到满足的一个立即返回】和findindex()【找到满足条件的一个,立即返回其索引】

[1,5,10,15].find((value,index,arr)=>{
    console.log(value,index,arr)
    return value>9
})
//结果:10
[1,5,10,15].findindex((value,index,arr)=>{
    console.log(value,index,arr)
    return value>9
})
//结果:2

6.Object.assign(目标对象,源对象1,源对象2,...):

合并对象(可以合并多个对象)

const apple={
    color:'red',
    shape:'球形',
    taste:'甜'
};
const pen={
    color:'black',
    shape:'圆柱形',
    use:'写字'
}
console.log(Object.assign(apple,pen))
//结果:{color:'black',shape:'圆柱形',taste:'甜',use:'写字'}

console.log(Object.assign(apple,pen)===apple)
//结果:true

6.1:注意事项

(1)基本数据类型作为源对象,与对象的展开类似,先转换成对象,再合并。

(2)Object.assign()直接合并到了第一个参数中,返回的就是合并后的对象,因此目标对象一般用空对象。

(3)同名属性的替换:后面的直接覆盖前面的。

6.3应用

//合并默认参数和用户参数
const logUser=userOptions=>{
    const DEFAULTS={
        username:'ZhangSan',
        age:18,
        sex:'male'
    };
    const options=Object.assign({},DEFAULTS,userOptions);
    console.log(options)
}
logUser();

7.Object.keys()、Object.values()和Object.entries()

const person={
    name:'alex',
    age:18,
    sex:'male'
};
console.log(Object.keys(person));
//['name','age','sex']
console.log(Object.values(person));
//['alex',18,'male']
console.log(Object.entries(person));
//[['name','alex'],['age',18],['sex','male']]

7.1与数组类似方法的区别:

(1)数组的keys()、values()、entries()等方法是实例方法,返回的都是iterator。

                                

(2)对象的Object.keys()、Object.values()、Object.entries()等方法是构造函数方法,返回的是数组。

const person={
    name:'alex',
    age:18,
    sex:'male'
}
for(const key of person ){
    console.log(key)
}
//打印报错,因为person不是Iterator,可以如下这样做
for(const key of Object.keys(person)){
    console.log(key)
}

(3)Object.keys()、Object.values()、Object.entries()等方法并不能保证顺序一定是你看到的样子,这一点和for in 是一样的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

愿~~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值