初识ES6

let 与 const

  • var:ES5中用于声明变量的关键字,存在各种问题,例如
  •  // 1.声明提升
     console.log(name); //哈哈
     var name = "哈哈";
     
     // 2. 变量覆盖,发生变量覆盖可能会导致数据丢失以及各种不可预知的bug
     var demo = "小明";
     var demo = "小红";
     console.log(demo)//小红
    
    // 3. 没有块级作用域,i是定义在循环体之内的,原则上讲只能在循环体内打印
      function fn2(){
          for(var i = 0; i < 5; i++){
              
          }
          console.log(i); //5
      }
      fn2();
    
  • let:ES6新增,用于声明变量,有块级作用域  下面换成let就不会存在上述问题:

  •  // 1. 不会存在声明提前,必须先声明
     console.log(name); //此处会报错
     let name = "哈哈";
     
     // 2. 不会有变量覆盖
     let demo = "小明";
     let demo = "小红";
     console.log(demo)// 此处会报错 告诉你已经定义了此变量
    
    // 3. 有块级作用域
      function fn2(){
          for(let i = 0; i < 5; i++){
              
          }
          console.log(i); // 此处会报错,无法打印
      }
      fn2();
    
  • const:ES6新增 声明一个只读的常量,一旦声明,常量的值就不能改变
  • 一般用于全局变量
  • 通常变量名全部大写(请按照规则来,不要乱搞,容易出事情)
const PI = "3.1415926";

解构赋值

  • 解构赋值是对赋值运算符的扩展
  • 针对数组或者对象进行模式匹配,然后对其中的变量进行赋值
  • 代码简洁且易读,语义更加清晰明了,方便了复杂对象中数据字段获取
  • 如果解构不成功,变量的值就等于undefined

1 对象解构赋值

let url = { username: "小红", password: "123455" };
let { username, password } = url;
console.log(username); //"小红"
console.log(password); //"123455"

2 数组解构赋值

let [, , third] = ["foo", "bar", "baz"];
console.log(third);// "baz"

3 函数参数的解构赋值

 function move({ x = 0, y = 0 } = {}) {
        return [x, y];
      }
      console.log(move({ x: 3, y: 8 })); // [3, 8]
      console.log(move({ x: 3 })); // [3, 0]
      console.log(move({})); // [0, 0]
      console.log(move()); // [0, 0]

[...]扩展运算符

用三个点号表示,功能是把数组或类数组对象展开成一系列用逗号隔开的散列值。

将数组展开为函数的参数

如果一个函数需要接收多个参数,而这些参数已经存储在一个数组中,那么使用扩展运算符可以很方便地将数组展开为函数的参数,避免手动指定每个参数

例1.

function myFunction(a, b, c) {
    console.log(a, b, c);
}

const arr = [1, 2, 3];
myFunction(...arr); // 相当于 myFunction(1, 2, 3);

例2. 

    function fun(name, age, city) {
        console.log(`Name: ${name}, Age: ${age}, City: ${city}`);
    }
    const person = ['Alice', 30, 'New York'];
    fun(...person); // Name: Alice, Age: 30, City: New York

复制数组

const array = [1, 2, 3];
const copiedarray = [...array];
console.log(copiedArray); // 输出 [1, 2, 3]

合并数组

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combinedArray = [...arr1, ...arr2];
console.log(combinedArray); // 输出 [1, 2, 3, 4, 5, 6]

浅拷贝

const obj1 = { key1: 'value1', key2: 'value2' };
const obj2 = { ...obj1, key3: 'value3' }; // 创建一个新对象,包含 obj1 的所有属性和新属性 key3
console.log(obj2); // 输出 { key1: 'value1', key2: 'value2', key3: 'value3' }

rest 参数

也是三个点号(形式为...变量名),不过其功能与扩展运算符恰好相反,把逗号隔开的散列组合成一个数组(返回数组就说明可以使用数组的一些方法),用于获取函数的多余参数

多个参数使用时rest 参数必须放在最后

 function fun(a, b, ...values) {
      console.log(a); //1
      console.log(b); //2
      console.log(values); //[3, 4, 5, 6]
    }
    fun(1, 2, 3, 4, 5, 6);

模板字符串

  • 模板字符串相当于加强版的字符串,用反引号 ``
  • 除了作为普通字符串,还可以用来定义多行字符串,可以在字符串中加入变量和表达式

1 普通字符串

// 普通字符串
let ttring = "hello"+"小兄弟"; 
console.log(ttring);// hello小兄弟

// 如果想要换行\n
let tring = "hello'\n'小兄弟"
console.log(tring);// hello
                  // 小兄弟

2 模板字符串

let str1  = "穿堂而过的";
let str2 = "风";
// 模板字符串
let newStr = `我是${str1}${str2}`;
console.log(newStr)// 我是穿堂而过的风

// 字符串中调用方法
function fn3(){
  return "帅的不行!";
}
let string2= `我真是${fn3 ()}`;
console.log(string2);  // 我真是帅的不行!

箭头函数

  • 箭头函数是一种更加简洁的函数书写方式
  • 箭头函数本身没有作用域(无this)
  • 箭头函数的this指向上一层,上下文决定其this
  • 基本语法:参数 => 函数体

 a. 基本用法

let fn = v => v;
//等价于
let fnn = function(num){
 return num;
}
fnn(100);  
console.log(fnn(100));// 输出100

b. 带参数的写法

let fn2 = (num1,num2) => {
 let result = num1 + num2;
 return result;
}
fn2(3,2);  
console.log(fn2(3,2));// 输出5

c. 箭头函数中的this指向问题

  • 箭头函数体中的 this 对象,是定义函数时的对象,而不是使用函数时的对象。在函数定义的时候就已经决定了
function fn3(){
  setTimeout(()=>{
    // 定义时,this 绑定的是 fn3 中的 this 对象
    console.log(this.a);
  },0)
}
var a = 10;
// fn3 的 this 对象为 {a: 10},因为它指向全局: window.a
fn3.call({a: 18});  // 改变this指向,此时 a = 18

 Class类

  • class (类)作为对象的模板被引入,可以通过 class 关键字定义类
  • class 的本质是 function,同样可以看成一个块
  • 可以看作一个语法糖,让对象原型的写法更加清晰
  • 更加标准的面向对象编程语法

1 类的定义

// 匿名类
let Demo = class {
    constructor(a) {
        this.a = a;
    }
}
// 命名类
let Demo = class Demo {
    constructor(a) {
        this.a = a;
    }
}

2 类的声明

  • 类不能重复声明
  • 类定义不会被提升,必须在访问前对类进行定义,否则就会报错。
  • 类中方法不需要 function 关键字。
  • 方法间不能加分号
class Demo {
    constructor(a) {
        this.a = a;
    }
}

3 类的主体

  • 公共属性(依然可以定义在原型上)
    class Demo{}
    Demo.prototype.a = 2;
    
  • 实例属性
    class Demo {
        a = 2;
        constructor () {
            console.log(this.a);
        }
    }
    
  • 方法:constructor
    class Demo{
        constructor(){
          console.log('我是构造器');
        }
    }
    new Demo(); // 我是构造器
    

    5.4 实例化对象

    class Demo {
        constructor(a, b) {
            this.a = a;
            this.b = b;
            console.log('Demo');
        }
        sum() {
            return this.a + this.b;
        }
    }
    let demo1 = new Demo(2, 1);
    let demo2 = new Demo(3, 1);
    // 两者原型链是相等的
    console.log(demo1._proto_ == demo2._proto_); // true
    

    Map()

  •  Map 是一个构造函数,通过 new 生成 Map 数据结构实例。 类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应。

1 Maps 和 Objects 的区别 

  • 一个 Object 的键只能是字符串或者 Symbols,但一个 Map 的键可以是任意值
  • Map 中的键值是有序的(FIFO 原则),而添加到对象中的键则不是
  • Map 的键值对个数可以从 size 属性获取,而 Object 的键值对个数只能手动计算

    //声明
    let m = new Map();
    //添加元素
    m.set('name', '小红');
    console.log(m); //key: "name" value: "小红"

2 Map中的key

// 1. key是字符串
let myMap = new Map();
let keyString = "string"; 
 
myMap.set(keyString, "和键'string'关联的值");

// keyString === 'string'
myMap.get(keyString);    // "和键'string'关联的值"
myMap.get("string");   // "和键'string'关联的值"

// 2.key是对象
let myMap = new Map();
let keyObj = {}, 
 
myMap.set(keyObj, "和键 keyObj 关联的值");
myMap.get(keyObj); // "和键 keyObj 关联的值"
myMap.get({}); // undefined, 因为 keyObj !== {}

// 3. key也可以是函数或者NaN                         

3 Map 的迭代

// 1.使用 forEach
let myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
 
// 0 = zero , 1 = one
myMap.forEach(function(value, key) {
  console.log(key + " = " + value);
}, myMap)

// 2. 也可以使用 for...of

4 Map 与 Array的转换

letkvArray = [["key1", "value1"], ["key2", "value2"]];
 
// Map 构造函数可以将一个 二维 键值对数组转换成一个 Map 对象
let myMap = new Map(kvArray);
 
// 使用 Array.from 函数可以将一个 Map 对象转换成一个二维键值对数组
let outArray = Array.from(myMap);

5 Map和ForEach 的区别

     .forEach() 适合于你并不打算改变数据的时候,而只是想用数据做一些事情

let arr = ['a', 'b', 'c', 'd'];
arr.forEach((val) => {
 console.log(val); // 依次打印出 a,b,c,d
});
  • map() 适用于你要改变数据值的时候,它更快,而且返回一个新的数组
    let arr = [1, 2, 3, 4, 5];
    let arr2 = arr.map(num => num * 2).filter(num => num > 5);
    console.log(arr2);// arr2 = [6, 8, 10]
    

set

    var s2 = new Set(['小明', '小兰', '小红']);
    console.log(s2, 's2'); //{'小明', '小兰', '小红'}
    //删除元素
    s2.delete('小明');
    console.log(s2, 's2'); //{'小兰', '小红'}
    //检测元素是否存在
    console.log(s2.has('小明')); //false
    //清空
    s2.clear();
    console.log(s2, 's2'); //Set(0) {}
数组去重
    let arr = [1, 2, 3, 4, 5, 6, 2, 3, 1];
    let result = [...new Set(arr)];
    console.log(result); //1, 2, 3, 4, 5, 6
交集,相同的地方,包含
    let arr = [1, 2, 3, 4, 5, 6, 2, 3, 1];
    let arr1 = [4, 5, 6, 5, 6];
    let result1 = [...new Set(arr)].filter(item => {
        let s2 = new Set(arr1);
        if (s2.has(item)) {
            return true;
        } else {
            return false;
        }
    });
    console.log(result1); //4, 5, 6

简写:

let result1 = [...new Set(arr)].filter(item => new Set(arr1).has(item));
并集
    let arr = [1, 2, 3, 4, 5, 6, 2, 3, 1];
    let arr1 = [4, 5, 6, 5, 6];
    let union = [...new Set([...arr, ...arr1])];
    console.log(union); // [1, 2, 3, 4, 5, 6]
差集,A里面有B里面没有,交集的逆运算
    let arr = [1, 2, 3, 4, 5, 6, 2, 3, 1];
    let arr1 = [4, 5, 6, 5, 6];
    let result1 = [...new Set(arr)].filter(item => !(new Set(arr1).has(item)));
    console.log(result1); //[1, 2, 3]

for...of 循环

可以使用的范围包括数组、Set 和 Map 结构、某些类似数组的对象(比如 arguments对象、DOM NodeList 对象)、字符串。 for...of 不能遍历普通 Object 对象。 for...in 循环,只能获得对象的键名,不能直接获取属性值。 for...of 循环,允许遍历获得属性值。


Promise

   //实例化Promise,resolve参数成功,reject参数失败
    const p = new Promise((resolve, reject) => {
        setTimeout(function() {
            let data = '数据库中的用户数据';
            resolve(data, '成功');
            let err = '数据读取失败';
            reject(err, '失败');
        }, 1000)

    });
    //调用then方法
    p.then(function(value) {
        console.log(value, '成功')
    }, function(reason) {
        console.log(reason, '失败')
    })

使用Promise封装AJAX请求
   const p = new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        xhr.open('GET', 'https://api.xxx.com/xx');
        xhr.send();
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4) {
                if (xhr.status >= 200 && xhr.status < 300) {
                    resolve(xhr.response)

                } else {
                    reject(xhr.status)
                }
            }
        }
    })
    p.then(function(value) {
        console.log(value, '成功');
    }, function(reason) {
        console.log(reason, '失败');
    })

async/await 

async 也是处理异步的,它是对 Promise 的一种扩展,让异步更加方便

async 函数返回一个 Promise 对象,可以使用 then 方法添加回调函数。当函数执行的时候,一旦遇到 await 就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。

Symbol

作用:给对象添加方法和属性,独一无二的

    //创建Symbol
    let s = Symbol();
    console.log(s, typeof s); //Symbol() 'symbol'
    //创建Symbol
    let s2 = Symbol('Symbol');
    let s3 = Symbol('Symbol');
    s2 === s3; //false

    //Symbol.for()创建
    let s4 = Symbol.for('Symbol');
    let s5 = Symbol.for('Symbol');
    s4 === s5; //true

例:给对象添加方法

   let game = {
        name: 'xiaohong'
    }
    let methods = {
        up: Symbol(),
        down: Symbol()
    }
    game[methods.up] = function() {
        console.log('up');
    }
    game[methods.down] = function() {
        console.log('down');
    }
    console.log(game); //{name: 'xiaohong', Symbol(): ƒ, Symbol(): ƒ}
    game[methods.up](); // 调用 up 方法,输出 'up'
    game[methods.down](); // 调用 down 方法,输出 'down'

迭代器

自定义遍历

    var arr = ['小明', '小兰', '小红']
    let iterator = arr[Symbol.iterator]();
    //调用next方法返回一个对象,value表示当前成员的值,done表示遍历是否结束
    console.log(iterator.next()); //value: '小明', done: false
    console.log(iterator.next()); //value: '小兰', done: false
    console.log(iterator.next()); //value: '小红', done: false
    console.log(iterator.next()); //value: undefined, done: true

案例:

        var arr = {
            age: '18',
            name: ['小明', '小兰', '小红'],
            [Symbol.iterator]() {
                let index = 0;
                return {
                    next: () => {
                        if (index < this.name.length) {
                            const result =  {value: this.name[index],done: false}
                            index++;
                            return result;
                        }else{
                            return {value: undefined,done: true}
                        }
                    }
                }
            }
        }
        for (let item of arr) {
            console.log(item);
        }

生成器

生成器其实就是一个特殊的函数
针对异步编程 纯回调函数 hode fs  ajax   mongodb

    function* gen() {
        console.log('hello');
        console.log('111');
    }
    let iterator = gen();
    iterator.next(); //hello
    iterator.next(); //111

案例:1s后控制台输出111,2s后控制台输出222,3s后控制台输出333,

setTimeout 是用于在指定时间后执行指定函数的 JavaScript 函数,属于异步编程的一种常见方式。调用 setTimeout 不会阻塞后续代码的执行,而是在等待指定的时间后将回调函数放入任务队列中,等待事件循环执行

    function noe() {
        setTimeout(() => {
            console.log('111');
            iterator.next();
        }, 1000)
    }

    function two() {
        setTimeout(() => {
            console.log('222');
            iterator.next();
        }, 2000)
    }

    function three() {
        setTimeout(() => {
            console.log('333');
            iterator.next();
        }, 3000)
    }

    function* gen() {
        yield noe(); //调用函数
        yield two();
        yield three();
    }
    let iterator = gen();
    iterator.next();

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值