一, 变量
1.var 关键字的弊端
var 关键字的弊端: 1. 可以重复声明变量; 2. 无法限制变量修改; 3. 没有会计作用域, 只有函数作用域.
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input type="button" value="按钮 1">
<input type="button" value="按钮 2">
<input type="button" value="按钮 3">
<script>
var oBtn = document.getElementsByTagName("input");
for(var i=0; i<oBtn.length; i++){
oBtn[i].onclick = function () {
alert(i); // 三个按钮都是 3
}
}
// 点击按钮 alert 出来的都是 3. 因为事件没触发时, for 循环已经遍历结束, 当事件触发时 i 的值已经是 3 了.
</script>
</body>
</html>
惯用的解决办法是将 onclick 写进一个匿名函数.
- for(var i=0; i<oBtn.length; i++){
- (function (i) {
- oBtn[i].onclick = function () {
- alert(i); // 三个按钮都是 3
- }
- })(i);
- }
2.let 和 const 关键字
let 和 const 关键字使得变量不可以被重复声明, 且变量具有块级作用域. 不同的是, let 用来声明变量, const 用来声明常量(不可被修改的常量).
注: 在 Java 中, Java: int a = 123; int a = 12; 报错, 变量不可以重复声明, 因为它存在堆内存中, 变量直接代表一块内存空间. 而对象的值存在堆中, 变量实际上这个对象的引用. js 的 var 同样应遵循这样的规则.
- // let 写法
- for(let i=0; i< oBtn.length; i++){
- oBtn[i].onclick = function () {
- alert(i); // 三个按钮都是 3
- }
- }
二, 数组
1. 解构赋值
- let arr = [1, 2, 3];
- // let a = arr[0];
- // let b = arr[1];
- // let c = arr[2];
- // 等价于
- let [a, b, c] = [1, 2, 3];
- console.log(a, b, c);
- let {l, m, n} = {l: 1, m:2, n:3};
- console.log(l, m, n);
- let [x, y, z] = [{p1: 123, p2: 234}, [345, 456], 789];
- console.log(x, y, z);
- let [{p11, p12}, [p21, p22], p31] = [{p11: 123, p12: 234}, [345, 456], 789];
- console.log(p11, p12, p21, p22, p31);
注意, 当右侧是一个 json 数据时, 左侧相应的变量必须与其键名对应.
2, 新增 map,reduce,filter,forEach 函数
常见的数组操作函数.
- // map: 用给定的映射遍历数组, 不改变原数组, 生成新数组;
- let arr = [12, 58, 99, 86, 45, 21];
- let newArr = arr.map(item=>item>=60?"及格":"不及格");
- console.log(arr, newArr);
- // reduce: 遍历累加
- let sum = arr.reduce((item1, item2, index)=>item1+item2); // index 表示下标, 这里可不写
- console.log(sum);
- // filter: 过滤器
- let filter = arr.filter(item=>item<=60);
- console.log(filter);
- let arr2 = [
- {title: "奔驰", price: 20},
- {title: "宝马", price: 35},
- {title: "路虎", price: 30},
- {title: "特斯拉", price: 40},
- {title: "大众", price: 15},
- {title: "标致", price:15},
- ];
- let filter2 = arr2.filter(item=>item.price>=30);
- console.log(filter2);
- // forEach 循环遍历
- let newArr2 = arr.forEach((item, index)=>console.log(item, index));
- newArr2; // 没有返
三, 字符串
1. 新增 startswith 和 endswith
- let str = "http://www.baidu.com";
- if(str.startsWith("https")){
- console.log("加密网址");
- }else if(str.startsWith("http")){
- console.log("普通网址");
- }
- let str2 = "abc1234@163.com";
- if(str2.endsWith("163.com")){
- console.log("163 邮箱");
- }else if(str2.endsWith("qq.com")){
- console.log("qq 邮箱");
- }
2. 模板字符串
用返单引号 (``) 包裹的字符串, 其中的变量可以用 ${}来替换. 它可以写多行字符串.
- let title="标题", content="内容";
- let str = `
- <div><h1>${title}</h1><p>${content}</p></div>
- `;
- alert(str);
四, 函数
1. 箭头函数
箭头函数是函数的一种简写.
- let show = function () {
- console.log("what the hell?")
- };
- show();
- // es6 写法
- let newShow = ()=>{
- console.log("what the hell?")
- };
- newShow();
带参数的写法. 如果参数只有一个, 那么 () 可以省略.
- let alt = a=>{console.log(a*10)};// 单个参数
- let add = (a, b) => {console.log(a + b);
- }; // 两个参数
- add(3,5);
如果函数只有一个返回值, 那么 {} 省略.
- let arr = [12, 234, 345, 64, 23, 87];
- arr.sort(function (n1, n2) { return n1 - n2 });
- // 简写为
- arr.sort((n1, n2) =>n1 - n2);
- console.log(arr);
2. 默认参数
可以像 python 那样在函数定义时设置默认参数的值. 并且可以通过...args 来展开元素, 同样类似 python 的 * args.
- function show2(a, b=4, c=123) {
- console.log(a, b, c);
- }
- show2(7);
- function show(a, b, ...args) {
- console.log(a + b);
- console.log(args); // 剩余的写进...args 数组里, 必须写在最后
- }
- show(3, 5, 7, 9, 11);
...args 甚至可以拆解数组.
- let arr1 = [1, 2, 3];
- let arr2 = [4, 5, 6];
- let arr = [...arr1, ...arr2]; // [1, 2, 3, 4, 5, 6]
五, json
如果键名和值一致, 那么键名可以省略.
- let a=123;
- let b=456;
- // 当名字和值一样时可以简写
- let json1 = {a, b}; // 等价于 let json1 = {a: a, b: b}
- let json2 = {
- a,
- b,
- show(item){
- console.log(item)
- } // 等价于 show: function(){console.log(item};
- };
- json2.show(json2.a);
六, 类
相比函数构造类的外挂式写法, 添加了 class 和 constructor 来声明类和构造函数.
- // 声明
- class Person{
- constructor(name, gender){
- this.name = name;
- this.gender = gender;
- }
- showName(){
- console.log(this.name);
- }
- showGender(){
- console.log(this.gender);
- }
- }
- var sun = new Person("孙悟空", "male");
- sun.showName();
- sun.showGender();
- // 继承
- class Child extends Person{
- constructor(name, gender, age){
- super(name, gender);
- this.age = age;
- }
- showAge(){
- console.log(this.age);
- }
- }
- var child = new Child("小猴子", "male", 12);
- child.showAge();
七, promise
用同步的写法来管理异步.
- function createPromise(url) {
- return new Promise(function (resolve, reject) {
- $.ajax({
- url, // url: url
- dataType: 'json',
- success(arr){ resolve(arr);},
- error(arr){vreject(arr);}
- })
- });
- }
- // 在当前目录下创建 arr.txt 和 json.txt 文件
- Promise.all([createPromise("arr.txt"), "json.txt"]).then(function (arr) {
- alert("全都成功了!");
- }, function (arr) {
- alert("至少有一个失败了!");
- });
高版本的 Jquery 中,$.ajax 本身就是 promise 对象, 所以上面的代码可简写为:
- Promise.all([$.ajax({url:"arr.txt", dataType:"json"}), $.ajax({url: "json.txt", dataType: "json"})]).then(function (results) {
- let [arr, json] = results;
- // 分别处理自己的逻辑
- console.log("全都成功了!");
- console.log(arr, json);
- }, arr=>alert("至少有一个失败了!"));
八, generator-yield
生成器. 惰性执行函数, 和 python 中的生成器一致.
- function *show() {
- console.log("------1-----");
- let a = yield 12;
- console.log("------2-----");
- console.log(a);
- return a;
- }
- let gen = show();
- let a = gen.next(123); // 当 yield 后赋值时, 第一次执行到 yield 时返回该值
- let b = gen.next(456);
- console.log(a, b); // a 是一个 json 对象
前端(七):ES6 一些新特性
来源: http://www.bubuko.com/infodetail-2689161.html