一、ES6 基本认识1、什么是 ES6?ES6 指的是 ECMAScript 6.0,是JavaScript 语言的一个标准。其目标是使JavaScript 可以用来编写复杂的大型的应用程序,成为企业级开发的语言。 2、ES6 与 JavaScript 的区别?ES6 是 JavaScript 的一个标准,JavaScript 是 ES6 的具体实现。 3、Babel 转码器? Babel 是一个被广泛使用的 ES6 转码器,其可以将 ES6 代码转为 ES5 代码,从而在现有环境下执行,即使用 ES6 编写代码而无需担心不能运行。 ES6 可以使用 箭头函数来 替代 普通函数,通过 Babel 转码器,可以将 箭头函数 转为 普通函数。这样就不需要去担心浏览器是否支持这种语法。 【ES6】 input.map(item => item + 1); 【ES5】 input.map(function (item) { return item + 1; });
二、常用特性1、let 命令(1)基本内容 (2)特性一:局部有效。 如下例:(看的可能有点绕,多瞅两遍) let 定义的是局部变量,对于 for 循环来说,每次循环都是不同的作用域,且 let 只对当前作用域有效。更有趣的是,循环语句内部是一个子作用域(即 在内部定义一个同名的 let 变量,不会影响外部的 let 变量)。看下面例子的第二个循环,每次循环操作,j 都是不同的值,且 循环内部 定义了 同名的 let 变量 j ,由于作用域的问题,其并不会影响循环语句中的 j,所以执行了全部循环。 【举例:】 var a = []; // 用来记录每次循环需要打印的初始值 var b = []; // 用来记录每次循环的初始值 var count = 0; // 用来记录循环的次数 for(var i = 0; i < 10; i++, count++) { a[i] = function() { console.log("当前循环的值 i 为: " + i); }; b[i] = i++; } console.log("当前循环执行次数为: " + count); // 由于 i 为全局变量,每次循环都会进行两次 i++,所以真实循环次数小于 10,所以输出为 5 a[6](); // 由于操作的都是同一变量,所以函数调用的是 最后一次修改的 i 值,所以输出为 10 console.log("每次循环的初始值 i 为: " + b); // 用于只进行了部分循环,所有数组有些并没有赋值,即为空值。所以输出为 0,,2,,4,,6,,8 console.log("循环执行后的 i 值: " + i); // i = 10 时退出循环, i 为全局变量,所以输出 为 10 var c = []; // 用来记录每次循环需要打印的初始值 var d = []; // 用来记录每次循环的初始值 var count = 0; // 用来记录循环的次数 for(let j = 0; j < 10; j++, count++) { let j = 5; c[j] = function() { console.log("当前循环的值 j 为: " + j); }; d[j] = j++; } console.log("当前循环执行次数为: " + count); // 由于 j 为 局部变量,循环内部定义的 let 同名变量 j (子作用域)不会影响 循环语句的 j,真实循环执行 10 次,所以输出为 10 c[5](); // 每次操作都是不同的变量,且执行了 j++ 操作,所以输出为 6 console.log("每次循环的初始值 j 为: " + d); // 由于内部每次都给 d[5] 赋值,其余元素均为空值,所以输出为 ,,,,,5 console.log("循环执行后的 j 值: " + j); // 由于 j 为局部变量,只能存在于 for 循环代码块中, 所以此处会报错,输出 ReferenceError: j is not defined
(3)特性二:不存在变量提升 【举例:】 console.log(a); // 不报错,输出 undefined console.log(b); // 报错,输出 ReferenceError: b is not defined var a = 10; let b = 20;
(4)特性三:暂时性死区 【举例:】 var tmp = 123; console.log(tmp); //不报错,输出 123 if (true) { console.log(tmp); // 报错,ReferenceError: Cannot access 'tmp' before initialization let tmp; } 第一次定义 tmp 为 var 型,所以可以正常输出 123, 进入 if 语句后,由于存在 let 定义的 tmp,系统判定 tmp 为局部变量而非全局变量。 导致 console.log(tmp) 中 tmp 出现在 变量声明前(变量提升失败), 从而报错,此处即为暂时性死区。
(5)特性四:不重复声明 【举例:】 // 报错,Identifier 'a' has already been declared { let a = 1; var a = 2; } // 不报错,undefined { var a = 1; var a = 2; } // 报错,Identifier 'a' has already been declared { let a = 1; let a = 2; }
2、const 命令(1)基本内容 【举例:(常量值不可被修改)】 const PI = 3.1415926 console.log(PI); // 输出 3.1415926 PI = 3.14 // 报错,输出 Assignment to constant variable. 【举例:(常量声明时需要初始化)】 const a // 报错,输出 Missing initializer in const declaration 【举例:局部有效】 { const PI = 3.1415926; } console.log(PI); // 报错,输出 PI is not defined 【举例:不存在变量提升】 { console.log(PI); // 报错,输出 Cannot access 'PI' before initialization const PI = 3.1415926; } 【举例:不重复声明】 { var PI = 3.14 const PI = 3.1415926; // 报错,输出 SyntaxError: Identifier 'PI' has already been declared }
(2)若 const 声明的是对象,那么 其不变的是 指向对象的地址,对象的值仍可以改变。可以通过object.freeze() 方法冻结对象(即对象不可修改)。 【举例:var,对象可被修改】 { var f = {name : 'tom', age : '12'}; console.log(f.name + ", " + f.age); // tom, 12 f.name = 'jarry'; f.age = 44; console.log(f.name + ", " + f.age); // jarry, 44 f = {name : 'rick', age : '22'}; console.log(f.name + ", " + f.age); // rick, 22 } 【举例:const,对象内容可被修改,但是对象不可被修改】 { const f = {name : 'tom', age : '12'}; console.log(f.name + ", " + f.age); // tom, 12 f.name = 'jarry'; f.age = 44; console.log(f.name + ", " + f.age); // jarry, 44 f = {name : 'rick', age : '22'}; // TypeError: Assignment to constant variable. } 【举例:freeze,对象不可被修改,对象内容不可被修改】 { const f = Object.freeze({name : 'tom', age : '12'}); console.log(f.name + ", " + f.age); // tom, 12 f.name = 'jarry'; f.age = 44; console.log(f.name + ", " + f.age); // tom, 12 f = {name : 'rick', age : '22'}; // TypeError: Assignment to constant variable. }
3、解构表达式(1)什么是解构? (2)数组的解构赋值 【未使用解构表达式给赋值:】 let a = 10; let b = 20; let c = 30; console.log(a, b, c); 【使用 解构表达式赋值:】 let [a, b, c] = [100, 200, 300]; console.log(a, b, c);
解构不成功时,对应的数据为 undefined。 【嵌套数组赋值:】 let [a, [b, [c, d]]] = [1, [2, [3, 4]]]; console.log(a, b, c, d); // 输出 1 2 3 4 let [head, ...tail] = [1, 2, 3, 4]; console.log(head); // 输出 1 console.log(tail); // 输出 (3) [2, 3, 4] let [x, y, ...z] = [1]; console.log(x); // 输出 1 console.log(y); // 输出 undefined console.log(z); // 输出 [] 【部分解构:(给匹配上的变量赋值)】 let [x, y, z] = [1, 2]; console.log(x); // 输出 1 console.log(y); // 输出 2 console.log(z); // 输出 undefined let [a, [b], c] = [1, [2, 3], 4]; console.log(a); // 输出 1 console.log(b); // 输出 2 console.log(c); // 输出 4 【解构时使用默认值:(即若赋值失败,可以使用默认值)】 function hello() { return "hello"; } let [x=hello(), y=hello(), z=100] = [1, 2, 3]; console.log(x); // 输出 1 console.log(y); // 输出 2 console.log(z); // 输出 3 let [x2=hello(), y2=hello(), z2=100] = [, 2, ]; console.log(x2); // 输出 hello console.log(y2); // 输出 2 console.log(z2); // 输出 100
(3)对象的解构赋值 【根据属性名匹配:】 let {name, age} = {name: "tom", age: 22}; console.log(name); // 输出 tom console.log(age); // 输出 22 【属性名匹配不成功,返回 undefined:】 let {name2, age2} = {name: "tom", age: 22}; console.log(name2); // 输出 undefined console.log(age2); // 输出 undefined 【自定义属性名匹配:】 let {name: name3, age: age3} = {name: "tom", age: 22}; console.log(name3); // 输出 tom console.log(age3); // 输出 22
4、字符串拓展 即加强了字符串处理功能。 \u1F680 会解析成 \u1F68 和 0。若想正常显示,需使用双字节 \uD83D\uDE80 表示。 【举例:】 console.log("\u0061"); // 输出 a console.log("\u00614"); // 输出 a4
ES6 可以使用 大括号将 xxxxx 括起来,从而正确解读。 【举例:】 console.log("\u{0061}"); console.log("\u{1F680}"); console.log("\uD83D\uDE80");
(2)新增方法 -- includes()、startsWith()、endsWith() 【举例:】 let test = "hello world"; console.log(test.includes("wo")); // 输出 true console.log(test.startsWith("he")); // 输出 true console.log(test.endsWith("ld")); // 输出 true console.log(test.includes("helloworld")); // 输出 false
(3)模板字符串(``) 【举例:】 let [name, age] = ["tom", 32]; function fun() { return "helloworld"; } let test2 = `${name}, age = ${age - 10}, say ${fun()}`; console.log(test2);
5、对象的拓展 拓展对象的用法。 【举例:】 let a = "hello"; let b = {a}; console.log(b); // 输出 {a: "hello"} let c = {a: a}; console.log(c); // 输出 {a: "hello"} let d = {g: "hello"}; console.log(d); // 输出 {g: "hello"}
对象中的方法也可以简写。 【举例:】 let [name, age] = ["tom", 32]; let person = { name, age, hello() { console.log(`${name}, ${age}`); }, hello2: function() { console.log(`${name}, ${age}`); } }; person.hello(); person.hello2();
(2)新增方法 -- assign() 【格式:】 Object.assign(target, source1, ...source2); 注: target 为目标对象,source1, ...source2 等都是源对象。 该方法是将 源对象 的值 复制 到 目标对象 中。 若出现同名属性,则后者会覆盖前者。 即 target、source1、source2 中存在同名属性,则最后 target 的那个同名属性为 source2 的属性。 【举例:】 let tom = { name: "tom", age: 32, teacher: { chinese: "rose", english: "jack" } }; let jarry = { name: "jarry", age: 33, email: "jarry@163.com" }; let people = Object.assign({}, tom, jarry); console.log(people); tom.teacher.chinese = "rick"; console.log(people);
如何实现深拷贝嘞: 将上例 let people = Object.assign({}, tom, jarry); 改为 let people = Object.assign({}, JSON.parse(JSON.stringify(tom)), jarry);
(3)新增对象遍历方法 -- keys()、values()、entries() 【举例:】 let people = { name: "tom", age: 22 }; console.log(Object.keys(people)); console.log(Object.values(people)); console.log(Object.entries(people));
(4)扩展运算符(...) 【举例:】 let people = { name: "tom", age: 22 }; let people2 = { name: "jarry", age: 33 }; console.log({people, people2}); console.log({...people, ...people2}); let a = [3, 1, 2]; console.log(a); console.log(...a);
6、函数的拓展(1)函数参数默认值 【举例:】 function test (x, y) { y = y || "hello"; console.log(x + "======" + y); } test("tom"); // 输出 tom======hello test("tom", "helloworld"); // 输出 tom======helloworld function test2 (x, y = "hello") { console.log(x + "======" + y); } test2("tom"); // 输出 tom======hello test2("tom", "helloworld"); // 输出 tom======helloworld
(2)rest 参数 【举例:】 function test (...values) { // for of 每次获取的是数组的值 for (let j of values) { console.log(j); } } test(8, 7, 9); function test2 (...values) { // for in 每次获取的是数组的下标 for (let j in values) { console.log(values[j]); } } test2(8, 7, 9); function test3 (...values, y) { // 报错,SyntaxError: Rest parameter must be last formal parameter for (let j in values) { console.log(values[j]); } }
(3)箭头函数 【使用箭头函数定义 函数:】 var f = v => v; console.log(f(3)); // 3 // 等价于 var f = function(v){ return v; } console.log(f(3)); // 3
如果没有参数、或者有多个参数,需使用圆括号 () 代替参数部分。 【使用 () 代替参数:】 var f = () => 5; // 等价于 var f = function () { return 5 }; var sum = (num1, num2) => num1 + num2; // 等价于 var sum = function(num1, num2) { return num1 + num2; };
如果方法体(代码块)存在多条语句,则需要使用大括号 {} 括起来,并使用 return 返回值。 【举例:】 var fun = () => { let num = 7; let num2 = num + 3; return num + num2; }; console.log(fun()); // 17 // 等价于 var fun = function() { let num = 7; let num2 = num + 3; return num + num2; }; console.log(fun()); // 17
若返回的是一个对象,则必须在对象外面加上圆括号 (),否则 {} 会被当成代码块被解析。 【举例:】 var getPeopleItem = id => ({ id: id, name: "Temp" }); console.log(getPeopleItem(3)); // {id: 3, name: "Temp"} var getPeopleItem = id => { id: id, name: "Temp" }; console.log(getPeopleItem(3)); // SyntaxError: Unexpected token :
解构与箭头函数可以一起使用: 【举例:】 let people = { name: "tom", age: 22 }; let fun = (param) => { console.log(param.name + "==========" + param.age); }; fun(people); let fun2 = ({name, age}) => { console.log(name + "==========" + age); }; fun2(people);
7、数组常用方法 参考:https://www.cnblogs.com/l-y-h/p/12150578.html 【举例:】 let arr = [4, 6, 5]; let newArr = arr.reduce((previousValue, currentValue, index, array) => { console.log("上一次处理的值为: " + previousValue); console.log("当前处理的值为: " + currentValue); console.log("当前元素下标为: " + index); console.log("当前数组元素为: " + array[index]); return currentValue * 2; }); console.log(newArr);
8、Promise 对象(1)什么是 Promise ? (2)Promise 特点 特点二:状态改变后,不再变化。 (3)Promise 缺点 (4)如何使用? 【格式:】 var promise = new Promise((resolve, reject) => { if(异步操作成功) { resolve(data); } else { reject(error); } }); promise.then((data) => { // 成功的操作 }).catch((error) => { // 失败的操作 });
9、模块化(1)什么是模块化? 模块化就是把代码进行拆分,方便重复利用。类似于 Java 中的各种 jar 包。 (2)export 命令 【导出方式一:】 export var test = "hello"; 【导出方式二:】 var a = "hello"; var b = [1, 2, 3]; export {a, b}; 导出方式一、导出方式二 对外暴露的接口名 为 变量名、函数名等。 使用 import 要填写正确的接口名,才能正常引用模块,否则会出错。 【导出方式三:(使用 as 自定义接口名)】 var a = "hello"; var b = [1, 2, 3]; export { a as AA, b as BB }; 【导出方式四:(使用 default 可以忽略接口名,此时 import 可以自定义接口名)】 export default { var a = "hello"; var b = [1, 2, 3]; }
(3)import 命令 【导入方式一:(使用 {} 可以一次接受多个模块接口名)】 import {a, b} from 'xx/xx.js'; 【导入方式二:(使用 as 取名)】 import {a as AA, b as BB} from 'xx/xx.js'; 【导入方式三:(对于 export default 的模块,可以任意取名)】 import test from 'xx/xx.js';
未完待续... |
|
来自: python_lover > 《待分类》