ES6


# var 与 let 的区别

# let 自带块级作用域 {} 代表块

if (5 > 3) {
  var num1 = 10;
  let num2 = 10;
}
console.log(num1); //10
console.log(num2); //出错

# let 不存在变量声明提升

console.log(a); // undefined
var a = 10;

console.log(a); // 出错
let a = 10;

# let 不允许重复声明

var a = 0;
var a = 10;
console.log(a); //10

let a = 0;
let a = 10;
console.log(a); //出错

# let 不会成为 window 对象的属性

# 变量的解构赋值

# 数组的解构赋值

let arr = [131, 182, 156];
//let num1 = arr[0];
//let num2 = arr[1];
//let num3 = arr[2];
let [num1, num2, num3] = arr;
console.log(num1, num2, num3); // 131 182 156

# 对象的解构赋值

// let {username} = {username:小黑}
let obj = {
  username: "小黑",
  userage: 20,
  sex: "女",
};
//let username = obj.username;
//let userage = obj.userage;
// 可以换名也可以设置默认值
let { userage: age, username, sex = "男" } = obj;
console.log(username, age, sex); //小黑 20 女
// 如果上边没有 sex 属性则结果为男
// 将 newPost对象中的属性全拿过来,同时加了id属性
addPost(newPost) {
    this.postList.push({ ...newPost, id: shortid() });
}

# 字符串的解构赋值

let str = "hello";
let [a, b, c, d, e] = str;
console.log(a, b, c, d, e); // h e l l o

# 函数参数的解构赋值

var obj = {
  username: "大白",
};
/* function say(obj) {
  const str = "我叫" + obj.username;
  console.log(str); // 我叫大白
} */
function say({ username }) {
  // 函数的形参相当于在函数内部声明变量,函数的实参相当于对这个形参变量赋值
  // let {username} = obj;
  const str = "我叫" + username;
  console.log(str); // 我叫大白
}
say(obj);

# 字符串扩展

# 模板字符串 (高级字符串拼接)

let goods = {
  name: "iphone12",
  price: 10000,
};

let htmlStr = `<div><h4>商品名${goods.name}</h4><span>商品价格${goods.price}</span></div>`;
console.log(htmlStr);

# padEnd padStart 填充

let str = "hello";
let newStr = str.padEnd(8, "a"); //往后填充,省略第二个参数默认用空格填
console.log(str); //hello
console.log(newStr); // helloaaa

# 数组扩展

# flat flatMap 数组的扁平化处理

数组的成员有时还是数组,用于将嵌套的数组 “拉平”,变成一维的数组。该两个方法返回一个新数组,对原数据没有影响。

let arr = [1, 2, [3, 4, [5, 6, [7, 8]]]];
console.log(arr.flat()); //默认只拉一层[1, 2, 3, 4, Array(3)]
console.log(arr.flat(2)); //[1, 2, 3, 4, 5, 6, Array(2)]
console.log(arr.flat(Infinity)); //不管有多少层嵌套,都要转成一维数组[1, 2, 3, 4, 5, 6, 7, 8]

let arr1 = [1, 2];
/* let newArr1 = arr1.map(function (ele) {
  return [ele, ele * 2];
});
console.log(newArr1); //[[1,2],[2,4]] */
let newArr1 = arr1.flatMap(function (ele) {
  return [ele, ele * 2];
});
console.log(newArr1); //[1, 2, 2, 4];
// flatMap相当于是先进行了一次Map操作,再进行一次flat操作

# fill 根据指定的数据对数组进行初始化,会修改原数组

let arr2 = [1, 2, 3];
// 原来的被修改了
console.log(arr2.fill("")); //["","",""]
console.log(arr2.fill(7, 1, 2)); //[1, 7, 3],因为会改变原数组,所以结果是没有上边那条输出语句
// 从第一个开始,到第二个之前结束 [1-2)

# 对象扩展

# 属性的简捷表示法

let name = "大白";
let age = 10;
/* let obj1 = {
  name: name,
  age: age,
  say: function () {
    console.log(this.name);
  },
}; */
let obj1 = {
  // 创建对象的时候,如果属性值所代表的变量名和属性名相同的话可以省略
  name,
  age,
  say() {
    console.log(this.name);
  },
};
console.log(obj1); //{name: "大白", age: 10, say: ƒ}

# 扩展运算符 …

用于复制拷贝

# 数组的扩展

let arr = [1, 2, 3, 4, 5];
let arr1 = arr;
arr1.push(6);
//因为是内置对象,所以拷贝的是地址
console.log(arr); //[1, 2, 3, 4, 5, 6]
console.log(arr1); //[1, 2, 3, 4, 5, 6]
console.log(arr1 === arr); //true

let arr = [1, 2, 3, 4, 5];
let arr1 = [...arr];
arr1.push(6);
console.log(arr); //[1, 2, 3, 4, 5]
console.log(arr1); //[1, 2, 3, 4, 5, 6]
console.log(arr1 === arr); //false

# 对象的扩展

let obj = {
  a: 10,
  b: 20,
};
let obj1 = { ...obj };
obj1.a = 100;
console.log(obj); //10 20
console.log(obj1); // 100 20

let goodsArr = [
  {
    name: "手机",
    price: 1000,
    id: 1,
  },
  {
    name: "平板",
    price: 2000,
    id: 2,
  },
  {
    name: "笔记本",
    price: 3000,
    id: 3,
  },
];
let newArr = [...goodsArr]; //只把最外边的拷贝了(只拷贝了数组),里边的地址没有拷贝
newArr[1].price = 2500;
console.log(newArr[1]); //2500
console.log(goodsArr[1]); //2500

# 函数的扩展

# 函数参数的默认值

function add(x = 10, y = 20) {
  return x + y;
}
let res = add(2);
console.log(res); //22

# …rest 参数

function fun(a, ...rest) {
  // rest 叫剩余参数,剩余参数必须写在后面
  console.log(rest); //(3) [2, 3, 4]
}
fun(1, 2, 3, 4);

# 箭头函数

let add = (x, y = 20) => x + y;
let res = add(10);
console.log(res); //30
//箭头函数,不能使用 function 创建,只能存储到变量中
//箭头左侧是参数部分用()包裹,没有参的时候直接写(),
//当只有一个参数的时候可以省略()直接写参数,右侧是执行部分,
//用{}包裹,当只有return的时候可以省略{},直接写返回值
// 当函数只返回对象的时候,可以直接({})
// let add = (x, y = 20) => ({})

let arr = [1, 3124, 145, 123, 1225, 6, 7];
// let newArr = arr.filter(function (ele) {
//   return ele < 10;
// });
let newArr = arr.filter((ele) => ele < 10);
console.log(newArr);

# 箭头函数和普通函数的 this 指向

// 普通函数的this指向:谁调用就指向谁
let obj = {
  a: 10,
  fun: function () {
    console.log(this); //{a: 10, fun: ƒ}
  },
};
obj.fun();

// 箭头函数的this指向:创建的时候就定义好了
// 对象内定义方法的时候如果方法内部使用了 this,那么这个方法就不能用箭头函数定义
let obj = {
  a: 10,
  fun: () => {
    console.log(this);
  },
};
obj.fun(); //Window

// 箭头函数一般都设置在类里面,因为外边找不到,一般都是window,
// 如果在外边涉及不到this那么箭头函数和普通函数没什么区别
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
  sayPoint = () => {
    console.log(this); //Point {x: 10, y: 100, sayPoint: ƒ}
  };
}
let p = new Point(10, 100);
p.sayPoint();

# symbol 数据类型 (简单看)

  • 简单用法

    let obj = {
      a: 10,
      a: 20,
    };
    console.log(obj); //a:20
    
    let s1 = Symbol("foo");
    let s2 = Symbol("foo");
    console.log(s1); //Symbol(foo)
    console.log(s1 === s2); //false
    console.log(s1.description); //foo
    
    let x = Symbol();
    let obj = {};
    let a = "say";
    obj[a] = function () {};
    obj[x] = "hello!";
    console.log(obj); //{Symbol(): "hello!", say: ƒ}

# Class 类

  • 基础用法

    /* function Point(x, y) {
      this.x = x;
      this.y = y;
    }
    Point.prototype.toString = function () {
      return `(${this.x},${this.y})`;
    };
    var p = new Point(1, 2); */
    
    let _color = "orange";
    class Point {
      // 类的内部必须存在 constructor 函数,当 new 的时候 constructor 函数被触发,
      // 该方法默认返回实例对象(this)
      // 除了 constructor 函数之外的函数都相当于公有方法,函数之间什么都不用加(逗号)
      // 类的内容默认只能写方法,向下边这样
      constructor(x, y) {
        this.x = x;
        this.y = y;
        console.log("constructor函数被触发");
      }
      // get 给 color 属性定义初始值
      get color() {
        return _color;
      }
      // get 设置的值要用set来改,会在修改 get 函数的时候触发
      set color(value) {
        // console.log(value);
        if (this.color !== value) {
          _color = value;
        }
      }
      toString() {
        return `(${this.x},${this.y})`;
      }
      // 静态函数 只有类本身可以访问,不会生成到类的实例上
      static sayHello() {
        console.log("hello");
      }
    }
    // 创建完类之后,也可以这样添加方法
    Point.prototype.say = function () {
      console.log("我是新加方法");
    };
    let p = new Point(1, 2); //必须要有new
    p.color = "pink"; //在这里触发 set 函数
    console.log(p); // constructor函数被触发 Point {x: 1, y: 2}
    console.log(p.toString()); //(1,2)
    p.say(); //我是新加方法
    console.log(p.color); //pink
    Point.sayHello(); //静态方法只能这样访问

# Class 类的继承

  • 基本用法

    class Point {
      constructor(x, y) {
        this.x = x;
        this.y = y;
      }
      sayPoint() {
        console.log(`我是坐标(${this.x},${this.y})`);
      }
    }
    let p = new Point(100, 20);
    console.log(p); //Point {x: 100, y: 20}
    p.sayPoint(); //我是坐标(100,20)
    
    // 类的继承使用关键字extends
    class ColorPoint extends Point {
      // 继承Point内的所有内容
      constructor(x, y, color) {
        // 当继承的类内部创建了 constructor,那么该函数内部必须使用 super 方法调用父类
        super(x, y);
        this.color = color;
      }
    }
    let colorP = new ColorPoint(100, 200);
    console.log(colorP); //ColorPoint {x: 100, y: 200, color: "red"}
    colorP.sayPoint(); //我是坐标(100,20)

# Es6 模块

# 使用 webpack 编译打包 es6 模块语法

  • 安装 node (去官网下载)
    node 是 js 的运行环境,里边有 js 的各种插件
    node -v 检查版本
    npm -v 检查版本

    npm config set registry https://registry.npm.taobao.org
    // 淘宝镜像
    
    npm config set loglevel=http
    // 下载的时候有显示
  • 安装命令行工具 git bash

  • 新建一个文件夹 (webpack-es6)

  • 在文件夹内部打开命令行工具执行 npm init -y 命令。该命令的作用是将这个文件夹变成 node 项目,从而让这个项目可以使用 npm 下载对应的包 (插件)。

  • 项目内安装 webpack 执行 npm install webpack webpack-cli --save-dev

  • 在项目的根目录下新建 index.html src/index.js src/a.js 在 a.js 内写一些 es6 模块代码 (导出变量) , index.js 内导入 a.js 模块内的导出

  • 在项目根目录下打开命令行工具执行 npx webpack 命令。该命令的默认作用是将项目下的 src 文件夹下的 index.js 打包并编译到某个文件夹 (dist 文件夹) 下的 main.js,然后 index.html 引入打包好之后的 js (main.js) 文件,在浏览器中查看

  • 如果更改 index.js 以及 a.js 需要重新执行 npx webpack 编译

# es6 模块的导入 (import) 导出 (export)

  • 简单操作

    • a.js 文件

      // 模块导出了一个变量 firstName(对外输出了一个变量)
      /* let lastName = "三";
      export let firstName = "张";
      export { firstName };
      //export { lastName as laName }; //换名,导出的是laName
      //export { firstName, lastName }; //导出多个 */
      
      let a = 10;
      let b = 20;
      let c = 30;
      let d = 10000;
      export { a, b, c };
      export default d;
    • b.js 文件

      let add = () => a + b;
      let res = add(1, 2);
      console.log(res); //3 因为在index.js中导入了
    • index.js 文件

      // 导入a.js模块导出的变量(加载这个变量)
      // 当导入模块的时候如果模块是js文件可省略后缀
      import "./b.js"; //相当于只是让b.js执行了,但里边的内容拿不到
      import { firstName } from "./a.js"; //这里也让a.js文件从上到下执行了一遍
      //每一个导入都会让 from 后的文件从头到尾执行一遍,而不是只执行某一个阶段
      console.log(firstName); //在html中引入main.js 文件,结果输出了 张
      
      import * as all from "./a";
      //* 代表导出的所有 as 是换名字
      import x from "./a"; //默认导入
      console.log(all.a); //10
      console.log(all.b); //20
      console.log(all.c); //30
      console.log(all.default); //10000
      console.log(x);
    • index.html 文件
      引入了 main.js 才生效

      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <title>Document</title>
        </head>
        <body>
          <script src="./dist/main.js"></script>
        </body>
      </html>
  • es6 有独立作用域,每一个模块都是一个独立作用域,当你导出的时候,另外一个模块只允许你导入我允许导出的东西

  • 命名导出 (export), 可以导出多次

  • 默认导出 (export default),只能使用一次

  • 1. 命名导入 (import) 导入的名称和导出的名称必须一致

    • * 代表导出的所有 as 是换名字
  • 2. 默认导入 (import) 导入的时候随意命名


文章作者: Mrr-cxh
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Mrr-cxh !
赏
 上一篇
ElementUI ElementUI
网站快速成型工具。Element,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库。
2021-02-26
下一篇 
JQuery JQuery
jQuery 是一个快速、简洁的 JavaScript 框架,是继 Prototype 之后又一个优秀的 JavaScript 代码库(框架)于 2006 年 1 月由 John Resig 发布。
2021-01-26
  目录