js简介(ES6方法)

ES6

变量声明

let: 声明变量

1)变量声明不会提前
2)let不允许相同作用域内多次声明同一变量
3)块级作用域 {}

演示:let声明变量的特点
1
2
3
4
let num = 666;//报错,不允许在同一作用域声明已存在的变量,其次变量声明不会提前
var num = 100;
var num = 10;
console.log(num);
案例:输出按钮索引值
//ES5方法
//相当于var i;
for(var i=0;i<btns.length;i++){
    btn[i].idx = i;
    btns[i].onclick = function(){
        setTimeout(function(){
            console.log(this.idx);
        }.bind(this),2000)
    }
}
//ES6方法:
for(let i=0;i<btns.length;i++){
    //相当于let i;
    btns[i].onclick = function(){
        setTimeout(function(){
            console.log(i);
        },2000)
    }
}
//考察知识点:
//1.变量的访问规则
//2.let的块级作用域{}

const:声明常量

1)变量声明不会提前
2)块级作用域
3)const不允许相同作用域内多次声明同一变量
4)声明后无法修改值

演示:
const MY_NAME = 'laoxie';
// 报错:无法修改常量的值
MY_NAME = 'LEMONE';
//演示:PI、Number()内置的一些常量属性

const常用于引用第三方库的声明

解构

声明变量时,从数组和对象中提取值,对变量进行赋值,这被叫做“解构” 。

数组解构

var [a,b] = [1,2];
console.log(a,b);//var a=1,b=2;

var [a,...b] = [1,2,3,4]; //...表示获取剩余参数
console.log(a,b); //var a=1,b=[2,3,4];

//(1)解构失败,得到undefined
var[a,b,c,d] = [10,20,30];
console.log(a,b,c,d);//d解构失败:数组arr中无对应索引值
var [a] = 1;//a解构失败,对应的右边不是数组,无法解构

//(2)指定默认值:
var [a=true]= 1; //当a解构失败的话,拿到默认值

对象解构

1
2
3
4
5
6
7
8
9
10
var obj = {name:"lemon",age:18};
var {name,age} = obj; // var name="lemon",age=18;
//(1)解构失败,得到undefined
var {username,age} = obj;//username解构失败,变量必须与对象属性名相同,否则为undefined

//(2)如果变量名与属性名不相同,则必须写成以下格式才能取到值
var {name:username,age} = obj; //声明的变量为username,解构obj中的name属性
//相当于:var username="lemon",age=18;
//(3)指定默认值:
var {a=10} = {};//当a解构失败的话,拿到默认值

应用

  • 交换变量值
    var [x,y] = [y,x];

    1
    2
    3
    var x = 10;
    var y = 20;
    var[x,y] = [y,x]; //相当于var x = 20;var y = 10;
  • 函数返回多个值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    //数组:
    function example(){
    return [1,2,3]
    }
    var [x,y,z] = example();
    //对象:
    function example(){
    return {name:"lemon",age:18};
    }
    var {name,age} = example();
  • 定义函数形参(重点)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    //数组:
    function test([x,y,z]){
    //相当于 var [x,y,z] = [1,2,3];
    }
    test([1,2,3]);
    //对象:
    function test({name,age}){
    //相当于 var {name,age} = {name:"lemon",age:18};
    }
    test({name:"lemon",age:18});

    //常规操作:参数可以设置默认值
    fuction test({x=0,y=0,z=0}){
    //相当于var {x=0,y=0,z=0} = {x:10}
    //为避免没有实参值传入,给形参默认值
    }
    test({x:10});

    //扩展:若形参是基本数据类型,函数也可以对形参进行设置默认值的操作。
    var func1 = function(x=1,y=2){return x+y};
    func1(); // 得到 3
    //同样,也可以用...表示获取剩余参数
    var func2 = (x, ...args) => { console.log(args) };
    func2(1,2,3); // 输出 [2,3]

字符串扩展

字符串方法

includes

​ 判断是否包含某个字符,返回布尔值

1
'html5'.includes('html');//true
startsWith/endsWith

​ 是否以某一字符或某一字符串开头/结尾

1
2
3
let str='google';
str.startsWith('goo'); //true
str.endsWith('e'); //true
repeat(n)

​ 得到字符串重复n次后的结果,n可以为小数,但不能为负数

1
'laoxie'.repeat(2);//laoxielaoxie

字符串模板template string (重点)

  • 使用反引号表示,你可以通过一种更加美观、更加方便的方式向字符串中插入变量
  • 格式:${变量|函数},
1
`你好,我的名字叫${username},接下来是我的自我介绍:${introduce()}`

模板字符串中所有的空格、新行、缩进,都会原样输出在生成的字符串中。

案例:根据数据生成一个商品列表

箭头函数arrow function(重点)

基本操作

  • 格式:标识符=>表达式

  • 省略了function、return关键字、圆括号、花括号

    //(一)函数内只有一句return代码,可省略{}及return。
    
    // 1. 零个参数用 () 表示
    
    var sum = function(){return 10 + 10;}  //  箭头函数: var sum = () => 10+10;
    
    // 2. 函数只有一个参数(可省略括号)
    
    var test = function(x){return x+2;}  // 箭头函数: var test = x=>x+2;
    
    // 3. 函数有多个参数,用(参数)表示
    
    var test = function(x,y){return x+y;}  // 箭头函数: var test =(x,y)=>x+y;
    
    //(二)函数中包含多行代码时用代码块括起来
    
    //ES6中的规则是,紧随箭头的{}被解析为块的开始,而不是对象的开始
    
     // ES5
    
    btn.onclick = function (e) {
    
      e = e || window.event;
    
      var keCode = e.which || e.keyCode;
    
      console.log(keyCode);
    
    };
    
    // ES6
    
    btn.onclick = e=>{
    
      e = e || window.event;
    
      var keyCode = e.which || e.keyCode;
    
      console.log(keyCode);
    
    };
    
    //(三)当使用箭头函数返回一个普通对象时,需要将对象包裹在小括号里
    //传统写法
    var createPerson = function(){
        return {name:'laoxie',age:18};
    }
    // ES6
    var createPerson = ()=>{name:'laoxie',age:18};   // 这样写会报Bug!
    var createPerson = ()=>({name:'laoxie',age:18});
    

箭头函数中的this值

箭头函数没有它自己的this值,箭头函数内的this值继承自外围作用域。

生成器函数 Generators

  • function和函数名之间有一个*号

  • yield :暂停代码执行

  • return:终止函数

  • next() : 执行后得到一个对象,有两个属性如下:

    • value:暂停时返回的值(yield)
    • done:表示函数是否执行完毕
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function* sum(x){
    console.log(1);
    yield 50;
    console.log(2);
    yield 100;
    console.log(3);
    // return 150;
    console.log('end');
    }
    var res = sum();//得到一个状态为suspended的对象{next()}
    // res.next();//得到一个对象:{value:xx,done:false}
    console.log(res);

Set集合

  • Set集合,类似于数组,但是成员的值都是唯一的,可自动去重。
  • 去重的前提是两个值恒等于。

set的方法

  • add(value):添加某个值,返回Set结构本身。
  • delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
  • has(value):返回一个布尔值,表示Set集合中是否存在该值。
  • clear():清除所有成员,没有返回值。
1
2
3
4
5
6
7
8
let imgs = new Set(); //创建一个set集合
imgs.add(1);
imgs.add(1);
imgs.add(5);
imgs.add("5");
imgs.add({name:"lemon"});
imgs.add({name:"lemon"});
//打印的结果: 1 5 '5' {name:"lemon"} {name:"lemon"}

利用set去重数组

1
2
3
4
var arr = [1, 2, 3, 4, 5, 5, 5, 5];
let items = new Set(arr);
//去重后将set集合重新转成数组
arr = Array.from(items);

遍历set集合

  • forEach()
  • for…of
1
2
3
4
5
6
7
8
set.forEach((item,idx)=>{
console.log(item,idx);
})

var imgs = new Set(['a','b','c']); //根据KEY遍历
for(let item of imgs){
console.log(item);
}

for…of

  • 这是最简洁、最直接的遍历数组元素的语法
  • 这个方法避开了for-in循环的所有缺陷
  • for…of跟for-in的区别很明显,就是直接取值,而不再取下标了
  • 与forEach()不同的是,它可以正确响应break、continue和return语句
1
2
3
4
var arr = [10,12,18,30];
for (var value of arr) {
console.log(value);
}

只要有[迭代器Symbol(Symbol.iterator) ]就可以用for…of遍历

  • Array
  • DOM
  • Set/Map集合
  • String
  • 不支持普通对象

对象扩展(重点)

对象合并方法

Object.assign(obj1,obj2,…objN); 合并对象到obj1,返回obj1

1
2
3
4
5
6
7
var obj1 = {a:1};
var newObj1 = Object.assign(obj1,{b:2});
//1.合并对象到obj1,所以obj1 = {a:1,b:2}
//2.返回obj1,传递给newObj1,所以newObj1 = {a:1,b:2}

var newObj2 = Object.assign(obj1,{b:2},{b:4,c:3});
//若存在相同属性,后面的覆盖前面的。//newObj=obj1={a:1,b:4,c:3}

扩展:对象的传递与复制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var obj = {
name:"laoxie",
hobby:['大保健','money']
}
//1.对象的传递:
var newObj = obj; //此时修改obj的任意属性,也会同时影响newObj
//2.对象的复制
//(1)for...in遍历复制
for(var key in obj){
newObj2[key] = obj[key];
}
//(2)利用assign()
var newObj3 = Object.assign({},obj);
//注意:以上两种复制方式,都只支持浅拷贝(对于引用类型,只拷贝引用)
obj.hobby.push('羽毛球');//此时也会影响newObj2与newObj3

//(3)深拷贝
var newObj3 = JSON.parse(JSON.stringify(person));

对象简写

ES6允许在对象之中直接写变量,如

1
2
3
4
5
6
7
8
9
10
11
12
13
//1. 属性简写
var myName = 'laoxie';
var obj = {myName};//等效于var obj = {myName:'laoxie'}。变量名作为属性名,变量值作为属性值。

//2.使用变量值作为属性名
var obj = {
[myName]:18 //等效于 laoxie:18
}

//3.方法简写
var obj = {
coding(){} //等效于 coding:function(){}
}

Map集合

js对象(Object)只能用字符串当作键(属性名)。这让它的使用有了很大的限制。所以ES6推出了一种类似于对象的数据集合:Map集合,它能让所有类型的数据作为键

常用方法

  • 设置set(key, value)
  • 获取get(key)
  • has(key)
  • delete(key)
  • clear()
1
2
3
4
5
6
7
8
9
10
11
12
//创建:
let map = new Map();

//设置:
map.set('name','laoxie');
map.set(6,666);
// 把数组作为键
var arr = [10,20,30];
map.set(arr,'数组');

//获取:
map.get(arr); //[10,20,30]

遍历方法

  • keys() 获取所有键,可以用Array.from()转成数组
  • values() 获取所有值,可以用Array.from()转成数组
  • entries() 获取所有键值对,可以用Array.from()转成数组
  • 循环遍历,配合解构赋值 for…of
1
2
3
4
5
6
7
for(var item of map){
console.log(item); //每个item得到的都是一个数组,索引0为键,索引1为值
}
//解构写法:
for(var [key,value] of map){
console.log(key,value);
}

Symbol数据类型

ES6引入了一种新的原始数据类型Symbol,表示独一无二的值,一旦创建后就不可更改,是一种类似于字符串的数据类型,但Symbol 值不能与其他类型的值进行运算,否则报错。

symbol的创建

1
2
3
4
5
6
7
8
9
10
11
12
// 没有参数的情况
var s1 = Symbol();
var s2 = Symbol();
s1 === s2 // false

//Symbol函数可以接受一个字符串作为参数,表示对Symbol实例的描述,主要是为了标识和区分,对调式非常有用
// 有参数的情况
var s1 = Symbol("foo");
var s2 = Symbol("foo");
s1 === s2 // false

//Symbol值不能与其他类型的值进行运算

symbol的用途

  • 给对象创建私有属性
  • 给现有的对象添加属性,可能会产生命名冲突,Symbol的出现解决这个问题
1
2
3
4
5
6
7
8
9
10
11
12
13
var attr = Symbol();

// 第一种写法,不用加引号
var a = {};
a[attr] = 'Nani';

// 第二种写法(注意加方括号,否则回被当作普通属性)
var a = {
[attr]: 'Nani';
};

// 以上写法都得到同样结果
a[attr] // "Nani"

Symbol.for() 登记symbol,会先查找当前Symbol是否存在

1
2
3
4
// 存在:则引用,不存在:则创建登记
var s11 = Symbol.for('laoxie');//创建一个Symbol
var s12 = Symbol.for('laoxie');//引用一个Symbol
//注意:直接使用Symbol()创建的Symbol值的键不会被登记,所以也就获取不到