阅读 44

es6 基础小结

let 和 const

创建变量的新语法,替换原来的 var

var num = 10;
console.log(num); // 控制台输出10
let num1 = 10;
console.log(num1); // 控制台输出10
const num2 = 10;
console.log(num2); // 控制台输出10
复制代码

let const 与 var 的区别

  • 自带块级作用域 {} 代表块
if (5 > 3) {
  var num = 100;
}
console.log(num); // 控制台输出: 100

if (5 > 3) {
  let num = 100;
  console.log(num); // 控制台输出: 100
}
console.log(num); // 控制台报错: num is not defined
复制代码
  • 没有变量声明提升
console.log(a); // 控制台输出: undefined
var a = 0;

console.log(b); // 控制台报错: Cannot access 'b' before initialization
let b = 1;
复制代码
  • 不允许重复声明
var a = 0;
var a = 50;
console.log(a); // 控制台输出: 50

let a = 0;
let a = 50;
console.log(a); // 控制台报错: Identifier 'a' has already been declared
复制代码
  • const 适用于创建常量,不可修改 比如:圆周率的 π
const num2 = 10;
num2++;
console.log(num2);
// 控制台报错提示 : Assignment to constant variable.
复制代码
  • 定义的变量不属于顶层对象(window)的属性
var a = 1;
console.log(window.a); // 控制台输出: 1

let b = 1;
console.log(window.b); // 控制台输出: undefined
复制代码

变量的解构赋值

  • 数组的结构赋值 数组的结构赋值要注意位置对应
let arr = [131, 182, 156];
// 定义变量取出数组内容
let num1 = arr[0];
let num2 = arr[1];
let num3 = arr[2];
console.log(num1, num2, num3); // 控制台输出 131 182 156

// 变量的结构赋值
let [num1, num2, num3] = arr;
console.log(num1, num2, num3); // 控制台输出 131 182 156
复制代码
  • 对象的结构赋值 对象的结构赋值要注意名字对应
let obj = {
  username: "小黑",
  userage: 20,
};

let username = obj.username;
let userage = obj.userage;
console.log(username, userage); // 控制台输出:小黑 20

// 对象的解构赋值
// 可以换名字 使用 :
// 可以换名也可以设置默认值
let { username, userage: age, sex = "男" } = obj;
console.log(username, age, sex); // 控制台输出:小黑 20 男
复制代码

如果要将一个已经声明的变量用于解构赋值:

let obj = {
  username: "小黑",
  userage: 20,
};
let username;
let age;
let sex;

let { username, userage: age, sex = "男" } = obj;
console.log(username, age, sex); // 控制台报错: Unexpected token ':'

({ username, userage: age, sex = "男" } = obj);
console.log(username, age, sex); // 控制台输出:小黑 20 男
复制代码
  • 字符串的结构赋值
let str = "hello";
let [a, b, c, d, e] = str;
console.log(a, b, c, d, e); // 控制台输出 h e l l o
复制代码
  • 函数参数的结构赋值
let obj = {
  username: "大白",
};

function say(obj) {
  const str = "我叫" + obj.username;
  console.log(str); // 控制台输出 我叫大白
}
say(obj);

// 函数参数的结构赋值
function say({ username }) {
  const str = "我叫" + username;
  console.log(str); // 控制台输出 我叫大白
}
say(obj);
复制代码

字符串的扩展

  • 模板字符串 (高级字符串拼接)
let goods = {
  goodsName: "iphone12",
  price: 10000,
};

// 字符串拼接
let htmlStr =
  "<div><h4>" +
  goods.goodsName +
  "</h4></span>" +
  goods.price +
  "</span></div>";
console.log(htmlStr);
// 控制台输出:<div><h4>iphone12</h4></span>10000</span></div>

// 模板字符串
let htmlStr1 = `<div><h4>${goods.goodsName}</h4></span>${goods.price}</span></div>`;
console.log(htmlStr1);
// 控制台输出:<div><h4>iphone12</h4></span>10000</span></div>
复制代码
  • padEnd padStart 填充
let str = "hello";
let newStr = str.padEnd(8, "a");
// 8 填充到的长度  'a' 用 a 填充

console.log(str); // 后台输出:helloaaa
console.log(newStr); // 后台输出:helloaaa
复制代码

新增数据类型

  • 标准数据类型 数字(Number) 字符串(String) 布尔值(Boolean) Undefined Null Object

  • 新增 BigInt(大整数) 为了与 Number 类型区别,BigInt 类型的数据必须添加后缀 n。

1234; // 普通整数
1234n; // BigInt

// BigInt 的运算
1n + 2n; // 3n
复制代码
  • 新增 Symbol(表示独一无二的值) Symbol()接收一个字符串作为参数,表示对 Symbol 的描述
let sym = Symbol("KK");
console.log(sym); // 控制台输出: Symbol(KK)
typeof sym; //  控制台输出:"symbol"

// 字符串参数相同,两个 Symbol 也不行等
let sym1 = Symbol("kk");
sym === sym1; // 控制台输出: false
复制代码

数组的扩展

  • flat() flatMap() 数组的扁平化处理

    flat()变成一维的数组,该方法返回一个新数组,不改变原数组。

let arr = [1, 2, [3, 4, [5, 6]]];
console.log(arr.flat()); // 控制台输出:(5) [1, 2, 3, 4, Array(2)]
// flat 默认扁平一次
console.log(arr.flat().flat()); // 控制台输出:(6) [1, 2, 3, 4, 5, 6]
console.log(arr.flat(2)); // 控制台输出:(6) [1, 2, 3, 4, 5, 6]
// flat(次数) 扁平化次数
console.log(arr.flat(Infinity)); // 控制台输出:(6) [1, 2, 3, 4, 5, 6]]
// flat(Infinity)用Infinity关键字作为参数,数组全部拉平
复制代码

flatMap()方法对原数组的每个成员执行一个函数,然后对返回值组成的数组执行 flat()方法,该方法不改变原数组。

let arr = [1, 2];
// 数组的 map() 方法
let newArr = arr.map(function (ele) {
  return [ele, ele * 2];
});
console.log(newArr); // 控制台输出:(2) [Array(2), Array(2)]

// 数组的 flatMap() 方法  相当于先对数组进行 map() 然后再进行一层 flat()
let arr1 = [1, 2];
let newArr1 = arr1.flatMap(function (ele) {
  return [ele, ele * 2];
});
console.log(newArr1); // 控制台输出:(4) [1, 2, 2, 4]
复制代码
  • fill() 根据指定的数据对数组进行初始化 此方法会修改原数组
let arr = [1, 2, 3];

console.log(arr.fill(100)); // 控制台输出:(3) [100, 100, 100]

console.log(arr.fill(7, 1, 2)); // 控制台输出:(3) [1, 7, 3]
复制代码

对象的扩展

  • 属性的简洁表示法 创建对象的时候属性值所代表的变量名和属性名重复可以省略,方法函数可以省略: function
// let name = "大白";
// let age = 10;
// let obj = {
//   name: name,
//   age: age,
//   say: function () {
//     console.log(this.name);
//   },
// };
let name = "大白";
let age = 10;
let obj = {
  name,
  age,
  say() {
    console.log(this.name);
  },
};
obj.say();
复制代码

扩展运算符 ...

扩展运算符用于拷贝的话只能实现浅拷贝

  • 数组的扩展
let arr = [1, 2, 3, 4, 5];
let arr1 = [...arr];
arr1.push(6);
console.log(arr); // (5) [1, 2, 3, 4, 5]
console.log(arr1); // (6) [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); // {a: 10, b: 20}
console.log(obj1); // {a: 100, b: 20}
复制代码
  • 函数的扩展
    • 函数参数的默认值
    // 函数参数默认值  设置了默认值 调用函数不传参数 显示结果
    function add(x = 10, y = 20) {
      return x + y;
    }
    // 传了参数 覆盖默认值
    let res = add(2);
    console.log(res); // 22
    复制代码
    • rest 参数 rest 剩余参数
    function fun(a, ...rest) {
      // rest 剩余参数 必须写在最后面
      console.log(rest);
    }
    fun(1, 2, 3, 4); // (3) [2, 3, 4]
    复制代码
    • 函数的新写法 箭头函数 箭头函数没有 function 不能使用 function 创建,只能写在变量中
      • 箭头函数分为箭头左侧和右侧
      • 左侧是参数部分,默认使用 () 包裹,当只有一个参数的是有可以省略 () ,直接写参数(没有参数写一个空的 () )
      • 右侧是执行部分,默认使用 {} 包裹,当函数右侧只有返回值的时候可以省略 {} 直接写返回值也不需要 return
      • 当函数只返回对象的时候可以直接 ({object})
    let add = (x, y = 20) => x + y;
    // let add = (x, y = 20) => {
    //   x = x * 2;
    //   return x + y;
    // };
    let res = add(10);
    console.log(res);
    复制代码
    箭头函数和普通函数的 this 指向问题:
    • 普通函数的 this 指向,谁调用了就指向谁
      let obj = {
        a: 10,
        fun: function () {
          console.log(this);
        },
      };
      obj.fun(); // {a: 10, fun: ƒ}
      let fun1 = obj.fun;
      fun1(); // Window
      复制代码
    • 箭头函数的 this 创建的是有就定义好了 对象内定义方法的时候,如果方法内部使用了 this ,那么这个方法不能使用箭头函数定义
      let obj = {
        a: 10,
        fun: () => {
          console.log(this);
        },
      };
      obj.fun(); // window
      let fun1 = obj.fun;
      fun1(); // window
      复制代码
    • 在类里面可以使用箭头函数 正确的 this 指向
      class Point {
        constructor(x, y) {
          this.x = x;
          this.y = y;
        }
        // sayPoint() {
        //   console.log(this.x, this.y);
        // }
        // 类里面的箭头函数 =
        sayPoint = () => {
          console.log(this.x, this.y);
        };
      }
      let p = new Point(10, 100);
      p.sayPoint(); // 10 100
      复制代码

Set 数据结构(构造函数)

Set 内部不允许出现重复的成员

const s = new Set();
// add 是 set 数据结构的一个方法,该方法的作用是向内部添加新的成员
// size 属性返回 Set 的个数(相当于数组的 length)
// delete 方法
// has 方法
// clear 方法
// forEach 方法
[2, 3, 5, 4, 5, "2", 2].forEach(function (ele) {
  s.add(ele);
});
console.log(s); // 控制台输出:Set(5) {2, 3, 5, 4, "2"}

// 新建 Set 内部要传递数组
let newS = new Set([1, 2, 3, 41]);
console.log(newS); // Set(4) {1, 2, 3, 4}

// Set 通过扩展运算符实现数组去重
let arr = [1, 2, 33, 4, 2, 2, 6, 8, 67, 76, 34, 23, 1, 6, 76];
console.log([...new Set(arr)]); // (10) [1, 2, 33, 4, 6, 8, 67, 76, 34, 23]
复制代码

Map 数据结构

Map 数据结构 类似于对象,也是键值对的集合,可以把各种类型的值(包括对象)当作键。

// 正常对象结构如果用数字表示'键'
let obj = {
  1: 200,
};
console.log(obj.1); // 会报错
复制代码

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);
console.log(p); // Point {x: 1, y: 2}
console.log(p.toString()); // (1,2)
复制代码
  • 创建类
    • 类的内部默认只能写方法
    • 类的内部必须存在 constructor 函数,当 new 的时候 constructor 函数被触发,该方法默认返回实例对象(this)
    • 除了 constructor 函数之外的函数都相当于公有方法
    • 类 完全可以看作构造函数的另一种写法
    • 实例的属性除非显式定义在其本身(this) 否则都是定义在原型上
    • get 和 set 关键字
let _color = "red";
class Point {
  // z = 50; // 属性的新写法  想到与字constructor内 this.z=50
  constructor(x, y) {
    this.x = x;
    this.y = y;
    console.log("constructor 执行了"); // 下面 出现 new 的时后 输出
  }
  // get color 属性定义初始值
  get color() {
    return _color;
  }
  // set 给 color 属性设置值,该函数会在修改 color 属性时触发
  set color(new_value) {
    _color = new_value;
  }
  toString() {
    return `(${this.x},${this.y})`;
  }
  // 静态方法
  // 只有类本身可以访问,不会生成到类的实力上,只能通过类访问
  static sayHello() {
    console.log("hello");
  }
}
let p = new Point(1, 2);
console.log(p); // Point {x: 1, y: 2}
console.log(p.toString()); //(1,2)
typeof Point; // "function"
Point === Point.prototype.constructor; // true

// 给类添加新的方法:
Point.prototype.say = function () {
  console.log("我是坐标"); // 我是坐标
};
p.say();

// Point {x: 1, y: 2}
// color: "red"
// x: 1
// y: 2
p.color = "blue";
console.log(p.color); // blue
// Point {x: 1, y: 2}
// color: "blue"
// x: 1
// y: 2

// p.sayHello(); // p.sayHello is not a function
Point.sayHello(); // hello
复制代码

class 的继承

类的继承使用关键字 extends

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)

class ColorPoint extends Point {
  // 需要继承 Point 内的所有内容

  // color = "red";

  // 上面是默认的 color  下面传参 color
  constructor(x, y, color) {
    // 当继承的类内部创建了 constructor 函数,那么该函数内部必须使用 super 方法调用父类的 constructor
    super(x, y);
    this.color = color;
  }
}
let colorP = new ColorPoint(100, 200, "red");
console.log(colorP); // ColorPoint {x: 100, y: 200, color: "red"}
colorP.sayPoint(); // 我是坐标(100,200)
复制代码

Module 模块

ES6 模块是通过 export 命令显式指定输出的代码,再通过 import 命令输入。 模块简单理解就是在一个 js 内部可以引用另外一个 js 的内容。

// 模块 es6.js
export var firstName = "Michael";
export var lastName = "jackson";
export var year = 1958;
复制代码
// index.js 使用模块内容
import { firstName } from "./js/es6.js";
console.log(firstName); // Cannot use import statement outside a module
// 直接这样用浏览器并不支持,需要运行在 node 环境中,或者通过 wabpack 编译
复制代码
Windows10 安装 Node.js
  1. 进入 Node 官网下载安装包(nodejs.org/zh-cn/) 建议下载长期支持版

Node官网.png node安装包.png

  1. 双击打开安装,直接下一步至安装完毕就可以,无需修改, win10 会自动加入环境变量
  2. 安装完成后打开命令行工具

安装完成.png

  1. 命令输入 node -v 显示 node 版本号即安装成功

node-v.png

打包编译
  • 打包工具 webpack
    • 使用 npm 下载
    • npm 设置国内淘宝镜像,命令行输入 npm config set registry https://registry.npm.taobao.org
    • npm 显示安装进度,命令行输入 npm config set loglevel=http
    • 在需要编译的项目文件夹,新建 webpack 存放文件夹,在这个文件夹下打开命令行工具执行:
      • npm init -y 完成之后会在文件夹生成 package.json 文件。 该命令的作用是将这个文件夹变成 node 项目,从而可以让这个项目使用 npm 下载对应的包
      • 安装 webpack 执行 npm install webpack webpack-cli --save-dev 完成后文件夹内出现 node_modules 文件夹和 package-lock.json 文件
      • 在项目的根目录下新建 index.html src/index.js a.js在 a.js 内写一些 es6 模块代码(导出变量)
      // a.js
      // 模块导出了一个变量 firstName
      export var firstName = "zhang";
      复制代码
      • 在 index.js 导入
      // index.js
      // 导入 a.js 模块导出的变量
      // 当导入模块的时候,如果模块是 js 文件可省略后缀
      import { firstName } from "./a";
      console.log(firstName);
      复制代码
      • 接下来,命令行工具执行 npx webpack,该命令的默认作用是将项目下的 src 文件夹下的 index.js 打包编译到 dist 下的 main.js,然后 index.html 引入打包好之后的 js 文件,在浏览器中查看
      • 如果更改了 index.js 以及 a.js 需要重新执行 npx webpack
模块的导出和导入
  • 命名导出 关键字 export 可以导出多次(可使用多次 export)

    export var firstName = "zhang";
    let lastName = "san";
    // export { lastName };
    
    export { lastName as laName };
    // 导出换名 lastName=>laName
    复制代码
    let a = 10;
    let b = 20;
    let c = 30;
    export { a, b, c };
    复制代码
  • 命名导入 导入的名称和导出的名称必须一致

    import { firstName, laName } from "./a";
    console.log(firstName, laName); // zhang san
    复制代码
    // * 表示导出的所有 | as 是换名字
    import * as all from "./a";
    console.log(all.a); // 10
    console.log(all.b); // 20
    console.log(all.c); // 30
    复制代码
  • 默认导出 关键字 export default 只能使用一次

    let a = 10;
    let b = 20;
    let c = 30;
    export { a, b, c };
    
    export default d;
    复制代码
  • 默认导入 导入的时候随意命名

    // * 包含所有(命名导出和默认导出)
    import * as all from "./a";
    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); // 10000
    复制代码
  • es6 模块全部由独立作用域 任何导入形式都会执行导入的 js

    // b.js
    let add = (a, b) => a + b;
    let res = add(1, 2);
    console.log(res);
    复制代码
    // 导入 b.js
    // 只是执行了 b.js 拿不到里面任何变量
    import "./b";
    // b.js 内 console.log(res) 执行
    console.log(add); // add is not defined
    复制代码
文章分类
前端
文章标签