ES6

内容纲要

let块级作用域

let和var的主要区别

  • let声明的变量只在当前(块级)作用域内有效
  • let声明的变量不能被重复声明
  • 不存在变量提升
  • 暂存死区(不能使用父级变量)

ES6之前的作用域

  • 全局作用域
  • 函数作用域
  • eval作用域

块级作用域

  • 通俗的讲就是一对花括号中的区域{ ... }
  1. if () {}
  2. switch () { }
  3. for() { }
  4. try{ } catch (err) { }
  5. { }
    块级作用域可嵌套

const

  • 常量-不可改变的量
    • 常量为引用类型的时候不能保证不可变(不能修改常量指向的地址)
      引用类型常量指向的是一个地址,修改地址内部的值是不会报错的]
    • 防止常量为引用类型的时候能被修改的情况
      Object.freeze(常量名)常量冻结
    • es6之前声明常量
    • 假装是常量
      var BASE_COLOR = '#ff0000';
    • Object.defineProperty(描述)
  • 和声明变量一样基本只是关键字的区别
  • 常量必须在声明的时候赋值
  • 否则报错: Missing initializer in const declaration

与let类似的特征

  • 不能重复声明
  • 不存在提升
  • 只在当前(块级)作用域内有效

解析赋值

解构赋值语法是一个JavaScript 表达式,这使得可以将值从数组或属性从对象提取到不同的变量中。--MDN

数组的解构赋值

//数组的解析结构赋值
const arr = [1, 2, 3, 4];
let [a, b, c, d] = arr;
let a = arr[1];
let b = arr[2];
let c = arr[3];
let d = arr[4];
//更复杂的匹配规则
const arr = ['a', 'b', ['c', 'd', ['e', 'f', 'g']]]
const [, b] = arr;
const [, , g]=['e', 'f', 'g'];
const [, , [, f]]=['c', 'd', ['e', 'f', 'g']];
const [, , [, , [, , g]]] = arr
//扩展运算符:...(扩展运算符为三个点)
const arr1 = [1,2,3];
const arr2 = ['a','b'];
const arr3 = ['zz',1];
const arr4 = [...arr1,...arr2,...arr3];
arr4
(7) [1, 2, 3, "a", "b", "zz", 1]
-----------------------------------
const arr = [1, 2, 3, 4];
const [a, b, ...c] = arr;
c
(2) [3, 4]
//默认值
const arr = [1, undefined, undefined];
const [a, b=2, c, d='aaaaa'] = arr;
// 交换变量
let a = 20;
let b = 10;
[a, b] = [b, a];
// let temp;
// temp = a;
// a = b;
// b = temp;
//  接受多个 函数返回值
function getUserInfo(id) {
    //...ajax
    return [
        true,
        {
            name:'小明',
            gender:'女',
            id:id
        },
        '请求成功'
    ];
};
const [status,data,msg]=getUserInfo(123);

对象的解构赋值

对象是无序的,可以直接通过属性名获取

//  对象的解构赋值
const  obj = {
    saber : 'niaho',
    archer: '卫宫'
};
// 匹配的时候需要保证属性名相同
const {saber,archer} = obj;
//  稍微复杂的解构条件
const player = {
    nickname: '唐僧洗头艹飘柔',
    master : '东海龙王',
    skill : [{
        skillName : '龙吟',
        mp:'100',
        time : 60000
    },{
        skillName : 'abc',
        mp:'100',
        time : 60000
    },{
        skillName : '123',
        mp:'100',
        time : 60000
    }]
}
const { nickname } = player;
const { master } = player;
// 数组状态下,数组中的数组中的属性名合法就ok
const {skill: [skill1, {skillName}, {skillName: sklName}]} = player;
const obj = {
    saber : '阿尔托利亚',
    archer : '卫宫',
    lancer : '实体店'
};
const {saber,...oth} = obj;
//使用扩展运算符合并对象

const obj = {
    archer: '卫宫',
    lancer: '实体店'
};
const obj1 = {
    saber: '阿尔托利亚',
    ...obj
};
// 默认值
let girlfrienf = {
    name : ' xiaohong',
    age : undefined,
    // hoby : ['看书',
    //     '洗澡']
};
let { name , age = 24, hoby = [ ' 学习']} = girlfrienf;
// 提取对象的属性

const { name , hobby:[hobby1] ,hobby } = {
    name : '小红',
    hobby : ['学习']
};
//  使用对象传入乱序的函数参数
function AJAX({
                  url,
                  data,
                  type = 'get',
              }) {
    // var type = option.type || 'get';
    console.log(type);
};
AJAX({
    url: 'getinfo',
    data:{
        a:1
    },
});
// 获取多个 函数返回值
function  getUserInfo(uid) {
    //...ajax
    return {
        status: true,
        data : {
            name : '小红'
        },
        msg : '请求成功',
        uid: uid
    };
};
const { status , data , msg ,uid} = getUserInfo(123);

字符串的解构赋值

const str = 'You is the bone of my sword';// 你是贱骨头
const [a, b, c,...d] = str;
// 字符串分解
const [...spStr1] = str;
const spStr2 =str.split('');
const spStr3 = [...str];
// 提取属性
const {length,split} = str;

数值与布尔值的解构赋值

const { valueOf: vo } = 1;
const { toString: ts} = false;

函数参数的解构赋值

function Computer({
                      cpu,
                      memory,
                      software = ['ie6'],
                      OS = 'windows 1909'
                  }) {
    console.log(cpu);
    console.log(memory);
    console.log(software);
    console.log(OS);
}
new Computer({
    memory:'1T',
    cpu:'i9',
    software:['idea'],
    OS:'mac'
});

ES6扩展

字符串扩展

  • 模版字符串
const xiaoming = {
    name: 'xiaoming',
    age: 14,
    say1: function() {
        console.log('我叫' + this.name.toUpperCase() + ', 我今年' + this.age + '岁!');
    },
    say2: function() {
        console.log(`我叫${ `Mr.${ this.name.toUpperCase() }` }, 我今年${ this.age }岁!`);
    }
}

xiaoming.say1();
xiaoming.say2();
// 列子
const getImoocCourseList = function() {
    // ajax
    return {
        status: true,
        msg: '获取成功',
        data: [{
            id: 1,
            title: 'Vue 入门',
            date: 'xxxx-01-09'
        }, {
            id: 2,
            title: 'ES6 入门',
            date: 'xxxx-01-10'
        }, {
            id: 3,
            title: 'React入门',
            date: 'xxxx-01-11'
        }]
    }
};
const { data: listData, status, msg } = getImoocCourseList();
function foo(val) {
    return val.replace('xxxx', 'xoxo');
}
if (status) {
    let arr = [];
    listData.forEach(function({ date, title }) {
        // arr.push(
        //  '<li>\
        //      <span>' + title + '</span>' +
        //      '<span>' + date + '</span>' +
        //  '</li>'
        // );
        arr.push(
            `
                <li>
                    <span>${ `课程名: ${ title }` }</span>
                    <span>${ foo(date) }</span>
                </li>
            `
        );
    });
    let ul = document.createElement('ul');
    ul.innerHTML = arr.join('');
    document.body.appendChild(ul);
} else {
    alert(msg);
}
  • 部分新的方法
// 部分新方法

// padStart padEnd 补全字符串长度
{
    let str = 'i';
// 往字符串前面补
    let str1 = str.padStart(5, 'mooc');
    console.log(str1);
// 往字符串后面补
    let str2 = str.padEnd(5, 'mooc');
    console.log(str2);
}
// repeat
{
    //重复字符串10遍
    console.log('i'.repeat(10));
    function repeat(str, num) {
        return new Array(num + 1).join(str);
    }
    console.log(repeat('s', 3));
}

// startsWith endsWith 判断字符串以什么开头或者以什么结尾
{
    const str = 'A promise is a promsie';
    console.log(str.startsWith('B'));
    console.log(str.startsWith('A pro'));
    console.log(str.endsWith('promsie'));
    console.log(str.endsWith('A'));
}

// includes 判断这个字符串中是否有该子字符串
{
    const str = 'A promise is a promise';

    // if (str.indexOf('promise') !== -1) {
    if (~str.indexOf('promise')) {
        console.log('存在1');
    }
    ~x = -(x + 1)
    if (str.includes('a promise')) {
        console.log('存在2');
    }
}
  • 新的Unicode表示法和遍历方式
let str = 'PROMISE';

/***************************************************************/
// ES6之前遍历字符串的方式
// 使用for循环
for (var i = 0, len = str.length; i < len; i ++) {
    console.log(str[i]);
    console.log(str.charAt(i));
}
/***************************************************************/
// 转成数组后遍历
var oStr = Array.prototype.slice.call(str);
var oStr = str.split('');
const oStr = [...str];
const [...oStr] = str;

oStr.forEach(function(word) {
    console.log(word);
});
console.log(oStr);
// 有时候遍历是为了操作字符串
// 对全是英文的字符串中的大写字符加密 A -> 100  B -> 99。。。
const map = {A: '100', B: '99', C: '98', D: '97', E: '96', F: '95', G: '94', H: '93', I: '92', J: '91', K: '90', L: '89', M: '88', N: '87', O: '86', P: '85', Q: '84', R: '83', S: '82', T: '81', U: '80', V: '79',W: '78',X: '77',Y: '76', Z: '75'};
const words = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';

oStr.forEach(function(word, index) {
    if (words.includes(word)) oStr[index] = map[word];
});

console.log(oStr.join(''));

/***************************************************************/
// 使用for-of遍历字符串,类似于java中的增强for循环
for (let word of str) {
    console.log(word);
}
let newStr = '';
for (let word of str) {
    if (words.includes(word)) newStr += map[word];
}
console.log(newStr)

/***************************************************************/
// 🐶 \u1f436 unicode码(点)。emoji

console.log('\u1f436');
console.log('\u{1f436}');

// Unicode是一项标准 包括字符集、编码方案等
// 他是为了解决传统的字符编码方案的局限而产生的,为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。

// codePointAt 获取字符串中对应字符的一个码点
// '🐶'.codePointAt(0);

// at 根据下标取字符
// '🐶abc'.at(0)     🐶

正则扩展

//正则表达是基础
const regexp1 = /^a/g; //匹配以a开头的字符串,g代表全局匹配
/*******************************/
const regexp2 = new RegExp('^a', 'g');
const regexp3 = new RegExp(/a/g);
const regexp4 = new RegExp(/a/);
console.log('aabbcc'.match(regexp1));
console.log('babbcc'.match(regexp1));
console.log('aabbccaabbaa'.match(regexp3));
console.log('aabbccaabbaa'.match(regexp4));
/*******************************/
// 构造函数的变化
const regexp5 = new RegExp(/a/giuy, 'ig');
/***************************/
// uy修饰符
// u.  unicode
console.log(/^\ud83d/.test('\ud83d\udc36'))
//u会将后面的当做一个字符处理
console.log(/^\ud83d/u.test('\ud83d\udc36'))

// '\ud83d\udc36'

// y 粘连修饰符   sticky 从上一个匹配结果的开始就满足匹配条件,才会执行下一次的匹配

const r1 = /imooc/g;
const r2 = /imooc/y;

const str = 'imoocimooc-imooc';

console.log(r1.exec(str));
console.log(r1.exec(str));
console.log(r1.exec(str));
console.log(r1.exec(str));

console.log('-----------------');

console.log(r2.exec(str));
console.log(r2.exec(str));
console.log(r2.exec(str));

数值扩展

新的进制表示法

// 新的进制表示法

// 016  =>  14

0o  0O    octonary   八进制
0b  0B    binary     二进制

console.log(0o16);
console.log(0b1111);

新的方法与安全数

  • Number.parseInt 转换为整数
  • Number.parseFloat 转换为浮点数
  • isNaN 判断一个值是不是NaN的,挂载Number下
  • ifFinite 判断一个数是不是有限的(Infinity-----无限的)
  • Number.isSafeInteger(); 这个数值是不是处在js能精确表示的范围之内(2的53次-1和负的2的53次-1)
    • Number.MAX_SAFE_INTEGER Number.MIN_SAFE_INTEGER
  • 幂运算
    • let a = 2 ** 10 ** 0 结果为2 幂运算默认为右运算,如需要打括号

函数扩展

默认参数

  • 函数参数的默认值
function People({ name, age = 38 } = {name: 1}) {
console.log(name, age);
};
People({ name: 3 });

与扩展运算符的结合

  • 结合扩展运算符(剩余参数...)
// 结合扩展运算符(剩余参数...)
// 扩展运算符是做展开
// 剩余参数是做聚合的
function sum(...args) {
//  // let args = Array.prototype.slice.call(arguments);
//  // let args = [...arguments];
//  // let [...args] = arguments;
    console.log(args);
}
sum(1, 2, 321, 4354, 'fdafsd');
// 输出结果为一个数组
/*******************************/
// 扩展用法  可以给多个参数,但是剩余参数必须是在最后一位
function op(type, b, ...nums) {
    console.log(type);
    console.log(nums);
}
op('sum', 1, 23, 454, 3, 67, 234);
/***************************/
//使用剩余参数计算总和
function sum(...numbers) {
    return numbers.reduce(function(a, b) {
        return a + b;
    }, 0);
}
console.log(sum(1, 2, 3, 4));

箭头函数(=>)

const add1 = (a ,b) => a + b;
//等效于
const add2 = function(a , b) {
    return a + b;
}
// 多行函数
const add1 = (a, b) => {
    a += 1;
    return a + b;
};
// 上下结果等效
const add2 = function(a, b) {
    a += 1;
    return a + b;
// 使用void可以让后面的表达式不返回或者返回一个undefined
const pop = arr => void arr.pop();
}
// 箭头函数和普通函数的区别
const log = () => {
    console.log(arguments);
};
箭头函数中没有arguments,只能通过扩展运算符接受剩余参数
const log = (...args) => {
    console.log(args)
}
箭头函数没有他自己的this,箭头函数的this指的是箭头函数所处环境的this->Window
const xiaoming = {
    name: 'xiaoming',
    age: null,
    getAge: function() {
        let _this = this;  // 对this做一个保留
        // ...ajax
        setTimeout(function() {
            _this.age = 14;
            console.log(_this);
        }, 1000);
    }
};
===============采用箭头函数==============
const xiaoming = {
    name: 'xiaoming',
    age: null,
    getAge: function() {
        // ...ajax
        setTimeout(() => {
            this.age = 14;
            console.log(this);
        }, 1000);
    }
};
在箭头函数中可以不采用保留this,箭头函数调用的this是所处环境中的this

对象扩展

简介表示法与属性名表达式

  • 简介表示法
//原
const getUserInfo = (id = 1) => {
    // AJAX ....
    const name = 'xiaoming';
    const age = 10;

    return {
        name: name,
        age: age,
        say: function() {
            console.log(this.name + this.age);
        }
    };
};
const xiaoming = getUserInfo();
------------------------------------------
//es6
const getUserInfo = (id = 1) => {
    // AJAX ....
    const name = 'xiaoming';
    const age = 10;
    return {
        name,
        age,
        say() {
            console.log(this.name + this.age);
        }
    };
};
const xiaoming = getUserInfo();
  • 属性名表达式
const obj = {
    a: 1,
    $abc: 2, // 以上可以通过obj.属性名访问
    'FDASFHGFgfdsgsd$#$%^&*%$#': 3 //通过obj['属性名访问']
};
const key = 'age';
const xiaoming = {
    name: 'xiaoming',
    [`${key}123`]: 14
};

部分新方法与扩展运算符

  • 复制对象 - 浅拷贝
    复制一个对象后,只是作为引用
  • 合并对象 - 浅拷贝
    在使用扩展运算符合并对象是,有相同属性名的变量将会使用靠后的哪一个对象的值
  • 部分新的方法和属性
    • Object.is -> === 全等于
      +0 -0 和NaN的判断时
    • Object.assign
      对数据进行合并
      const obj = Object.assign({a: 1}, {b: 2}, {c: 3}, {d: 4, e: 5});
      合并后
      obj={a:1,b:2,c:3,d:4,e:5}
    • Object.keys 返回自身key所组成的keys
    • Object.values 返回自身value所组成的值
    • Object.entries 返回每一组key value组成的数组
    • __ proto__ 代表当前对象的原型(了解)
    • super 可以访问到原型对象上的方法,只能是对象的简介表示法才行

数组扩展

THE END
分享
二维码
< <上一篇
下一篇>>