es6,es7,webpack 和 babel(爱前端)

npm install -g cnpm --registry=https://registry.npm.taobao.org

默认安装位置:

 一 ES6, ES7 简介和调试方法

1.1 简介

ECMAScript6 就是ECMAScript2015

ECMAScript7 就是ECMAScript2016

ECMAScript8 就是ECMAScript2017

ECMA组织2015年开始每年都要发布一个ECMAScript的新版本。

ECMAScript现在的语言实现就两个:JavaScript、ActionScript。

 1.2 浏览器调试

使用新版本的浏览器,就能调试一些 ES6, 7, 8 的语法 

在浏览器调试的时候,要有HTML的壳子,要有 script 标签

 

1.3 使用 NodeJS 调试

查看 node 版本: 命令行  node -v 回车

 运行结果:

1.4 使用 Babel 翻译

-g 安装的,一般叫做 CLI 程序 , commond line interface 命令行接口,这些命令可以在 CMD  窗口中使用

npm install -g cnpm --registry=https://registry.npm.taobao.org

默认安装位置:

运行上述代码后,我们能在 CMD 中运行 cnpm

 

1, babel 需要用 -g 安装  

   检查 babel 是否安装成功: babel --version

2, 到这一步,切换到项目目录下,创建一个文件  .babelrc 文件  rc 表示 resource 资源的意思

  windows 下不允许文件名以 . (点) 开头,解决:先建立一个文件,然后 rename xx.txt .babelrc

   文件内容: 

3 完成 .babelrc 之后,还要安装这个 preset 的依赖

  cnpm install --sava-dev babel-preset-es2015

   --save-dev表示在项目的 package.json 文件中的“devDependencies”字段列出,表示项目的开发依赖。

  就是说是在项目开发的时候,用的翻译器、打包工具、构建工具等等

  ps: 默认  babel 不认识  ... 语法 ,会报错,要装插件,让 babel 识别更多的语法 

  babel 的插件在 npm 库中都叫做 babel-plugin-***

  淘宝 NPM 镜像: https://npm.taobao.org/ 

4  装插件   npm install --save-dev @babel/plugin-syntax-object-rest-spread

   更改 .babelrc 文件,告诉 babel 我们要求你使用插件:

   

5 现在可以用 babel 命令进行翻译

  babel 02.js -o 0200.js

 

 二 const 和 let 

2.1 const    阮一峰的博客 

 const声明一个只读的常量。一旦声明,常量的值就不能改变。通常用 const 定义函数。

函数的定义一般来说都是不变的,所以今后的函数一律用 const 定义

 

 

const sum = function(a,b){
    return a + b;
}
console.log(sum(2,3));

const A = 12;
A = 8;  // 报错

 

一般来说所有字母要大写

2.2  let 

let 用来定义块级作用域变量。它的用法类似于 var,但是所声明的变量,只在 let 命令所在的代码块内有效

所谓的块级作用域指的是大括号、所有的语句体。

{
    var a = 1;
}
console.log(a);        //能够输出1

{
    let b = 2;
}
console.log(b);        //报错

 

 var定义的变量出了 { } 依然有定义,但是 let 出了 { } 没有定义了

今后,我们的所有的循环变量将用let来定义:

 

需要注意

1) 不管是 let 还是 const,都没有了变量声明的提升;

console.log(m); //报错,没有变量声明的提升;

let m = 100;

2) 不管是 let 还是 const,babel 一律翻译为 var。

 

三 变量的自动解构和剩余参数

3.1 自动解构

只有数组和对象能够自动解构。

ES6中允许从数组中提取值,按照对应位置,对变量赋值。对象也是一样的。

数组的解构

对象的解构

var [a,b,c] = [1,2,3];

console.log(a);

console.log(b);

console.log(c);

这里是 { } 

 

 

 

 

 

 

 对象的解构往往用在函数的形参列表中,调用函数的时候,传的对象(实参)就能够自动解构。

 1 function People({name,age,sex,yuwen,shuxue,yingyu}){
 2     this.name = name;
 3     this.age = age;
 4     this.sex = sex;
 5     this.yuwen = yuwen;
 6     this.shuxue = shuxue;
 7     this.yingyu = yingyu;
 8 }
 9 var xiaoming = new People({
10     "name" : "小明",
11     "age" : 12,
12     "sex" : "男",
13     "yuwen" : 34,
14     "shuxue" : 44,
15     "yingyu" : 66
16 });
17 
18 console.log(xiaoming);

 

3.2  剩余参数

在 c 变量之前加上...运算符,表示 c 现在接受所有剩余的参数

      

 需要注意的事情是:... 只能出现在最后一项 ,下面写法是错的

 var [a,...b,c] = [1,2,3,4,5,6,7]; 

 

let {x, y, ...z} = {x:1, y:2, a:3, b:4};
console.log(x);  // 1
console.log(y);  // 2
console.log(z);  // {a:3, b:4 }

let n = {x,y,...z};
console.log(n);  // {x:1, y:2, a:3, b:4} 

 

3.3 强制解构

在数组前面加上 ... 运算符,表示强制解构。这个数组将变为零散量

1 var arr = [1,3,32];
2 console.log(...arr);   // 1  3  32
3 
4 var str = [...arr];
5 console.log(str);   // [ 1  3  32 ]

 

 ... 运算符也可以作用于对象,通常用于一个情况:创建 obj1 的副本,仅仅改变 obj1 的某一(些)个属性

 

 1 var obj1 = {
 2     "a" : 1,
 3     "b" : 2,
 4     "c" : 3
 5 };
 6 
 7 var obj2 = {
 8     ...obj1 ,
 9     "b" : 8
10 };
11 
12 console.log(obj2);  

 运行结果: 

强制解构还可以用于类数组对象,可以将类数组对象变为真的数组

 

1 const fun = function(){
2     //下面的语句是一个奇淫技巧,是最快的将类数组对象变为数组的方法
3     var arr = [...arguments];
4     console.log(arr);        //[ 1, 2, 3, 4, 5, 6, 7, 8 ]
5     console.log(Array.isArray(arr)); //true
6 }
7 fun(1,2,3,4,5,6,7,8);

 

 如果用 babel 解构对象,需要安装 babel 的插件 babel-plugin-transform-object-rest-spread

 

四 数组的新方法

4.1  forEach 遍历数组

 

4.2 map()  

map() 返回一个新的数组,新数组的每一项是原数组的映射

例:是创建一个数组,每一项都是原来的数组的两倍

var arr = [12,432,2,25,6];
var newArr = arr.map(function(item){
    return item*2;
});
console.log(newArr);

 

注意:map() 出的数组,一定和原数组长度相同!

函数里面的的return就是新数组中这一项的数值

 4.3 filter()

例:从一个数组中,过滤一些项组合成新数组,此时使用 filter() 函数

var arr = [12,432,2,25,6];
var arr2 = arr.filter(function(item){
    return item %2 == 0;
});
console.log( arr2);   // [ 12, 432, 2, 6 ]

 

filter() 中有一个函数,这个函数 return 为 true 的项会被加入到新的数组中

例:再比如从一个数组中,提取所有及格组合成为新数组

var arr = [
    {"name":"小明" , "fenshu" :66},
    {"name":"小红" , "fenshu" :16},
    {"name":"小强" , "fenshu" :26},
    {"name":"小刚" , "fenshu" :86}
];
var arr2 = arr.filter(function(item){
    return item.fenshu >= 60;
});
console.log(arr2);  

 结果: 

 

4.4 reduce()

reduce 表示迭代遍历,每一项的遍历都可以使用遍历上一项的时候的结果。

reduce可以理解为“降阶”。

 

reduce里面的函数有两个参数,分别是a、b。

我们来探究 a、b 什么意思。所以我们直接输出a:

var arr = ["白板","幺鸡","二条","三万","四筒"];

arr.reduce(function(a,b){

    console.log(a);

});

var arr = ["白板","幺鸡","二条","三万","四筒"];

arr.reduce(function(a,b){

    console.log(b);

});

 少一项

 

 

 

 

 

 

  

 

 

reduce的机理

l  a 就表示遍历前一项的时候 return 的值,b 表示这一项的值。

l  系统会自动从下标为1的项开始遍历,遍历下标为1的项的时候,a 的值是第0项。

l  最后的一项的 return,就是总 return。

 

4.5 综合运用  map() , filter() , reduce() , 解构 (重要)

例:

var xiaoming = {
	"name" : "小明",
	"age" : 12,
	"sex" : "男",
	"friends" : [
		{
			"name" : "小红",
			"age" : 13
		},
		{
			"name" : "小强",
			"age" : 14
		},
		{
			"name" : "小刚炮",
			"age" : 18
		}
	]
}

题目1: 不允许更改小明,返回一个新对象,这个对象和小明相同,仅让小明的年龄变为 15岁

  

题目2:不允许更改小明,让小强的 age 变为 12

var xiaoming1 = {
    ...xiaoming, // 解构
    'friends': xiaoming.friends.map(function(item){
        if(item.name =='小强'){
            return {
                ...item,  // 解构
                'age': 22  // 修改为 22
            }
        }
        return item;  
    })
}
console.log(xiaoming1);

 

 题目3: 不允许更改小明,让小明只有 15 岁以下的朋友

var xiaoming1 = {
    ...xiaoming,
    'friends': xiaoming.friends.filter(function(item){
        return item.age < 15;  // 条件 年龄小于15岁
    })
}

 

 题目4:不允许更改小明,小明增加一个朋友, 老王,29岁

var xiaoming1 = {
    ...xiaoming,
    'friends': [...xiaoming.friends,{
        'name': '老王',
        'age' : 29
    }]
}

 

题目5:不允许更改小明,增加一个朋友,并且自动编号

在题目上,给每个 friends 添加 id

var xiaoming1 = {
    ...xiaoming,
    'friends' : [
        ...xiaoming.friends,
        {
            'id' : xiaoming.friends.reduce(function(a,b){
                return a.id > b.id ? a : b;  // 返回 id 大的一个
            }).id + 1,    // +1
            'name' : '老王',
            'age' : 29
        }
    ]
}

 

 不更改原来的对象,返回一个新对象,新对象是原来对象的增、删、改某些属性,这叫做函数式编程,也叫作兰姆达式编程

 

删除用 filter

改变用 map

增加用 ...

 作业:

var canting = {
    "name" : "全聚德",
    "cai" : {
        "liangcai" : [
            {
                "name" : "凉拌西红柿",
                "price" : 15
            },
            {
                "name" : "拍黄瓜",
                "price" : 18
            }
        ],
        "recai" : [
            {
                "name" : "宫保鸡丁",
                "price" : 25
            },
            {
                "name" : "红烧肉",
                "price" : 45
            },
            {
                "name" : "辣子鸡",
                "price" :15
            }
        ]
    }
}

// 宫保鸡丁 不卖了
var c = {
    ...canting,
    'cai' : {
        ...canting.cai,
        'recai' : canting.cai.recai.filter(function(item){
            return item.name != '宫保鸡丁';
        })
    }

}
// 宫保鸡丁 更改价格
var c = {
    ...canting,
    'cai' : {
        ...canting.cai,
        'recai' : canting.cai.recai.map(function(item){
            if(item.name == '宫保鸡丁'){
                return {
                    ...item,
                    'price' : 30
                }
            }
            return item;
        })
    }
}

// 增加一个新菜:红烧茄子,19元
var c = {
    ...canting,
    'cai' : {
        ...canting.cai,
        'recai' : [...canting.cai.recai,{
            'name' : '红烧茄子',
            'price' : 19
        }]
    }
}
//  售价 20 以上的热菜都不卖了
var c = {
    ...canting,
    'cai' : {
        ...canting.cai,
        'recai' : canting.cai.recai.filter(function(item){
            return item.price <= 20
        })
    }
}
console.log(JSON.stringify(c));  // console.log(c)  不能全部显示出来

 

 

//学习这个很关键,比如react的组件中有state(状态):
this.state = {
    a : 1, 
    b : [5,6,7,8], 
    c : 3
};
//修改的时候,不能更改原来的state。比如我们要把9加入到b属性中,正确:
this.setState({
    b : [...this.state.b , 9]
});

 

 4.6 includes() 方法

Array.prototype.includes 方法返回一个布尔值,表示某个数组是否包含给定的值。

之前我们判断数组中是否存在一项,此时用 indexOf() != -1(IE8开始兼容)。如果要IE6、7兼容,必须一项一项遍历比较。

ES6中,有了更简单的比较方法

 

注意,includes是全等比较,带着类型比较的 7  ‘7’

 

4.7 Array.from() 方法

Array.from 方法用于将类数组转为真正的数组

  结果:

 

五 对象的改变 

5.1 省略 v 

当一个对象的 k、v 相同(k 的名字和 v 的变量名相同),此时可以省略v

比如下面有三个变量a、b、c,要作为一个对象的属性名a、b、c,同时值也是1、2、3。

因为k、v一致,此时就可以省略v

  结果: 

注意,省略 v 的时候,k 不能有引号!

5.2 对象的方法现在可以简写

 

5.3 Object.keys() 和 Object.values()

Object.keys() 返回对象的键名数组;

Object.values() 返回对象的值数组;

  结果:

 

 5.4 Object.is()

ES5 比较两个值是否相等,只有两个运算符:相等运算符(==)和严格相等运算符(===)。

它们都有缺点,前者会自动转换数据类型,后者的 NaN 不等于自身,以及+0等于-0。

JavaScript 缺乏一种运算,在所有环境中,只要两个值是一样的,它们就应该相等

 

 

 5.5 Object.assign()

Object.assign 方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。

 结果:

注意 Object.assign() 可以有无限个参数,但是只会更改第一个参数对象

 

5.6 对象中键加方括号 -- 动态键

var sex = '女';
if(sex == '男'){        // 值判断
    var k = '身高'; 
} else {
    k = ' 视力';
}

var obj = {
    'name': 'rose',
    'sex' : sex,
    [k] : 'xxx'   // 动态键

}
console.log(obj);

 

 

 六 函数的改变 

6.1 箭头函数

下面的sum就是标准的箭头函数,省略掉了function这个关键字:

  =>是一个完整的运算符,之间不能有空格

如果函数体内只有一行语句,可以省略 {} 和 return

反过来,如果函数体内有多条语句,此时必须写 {} 和 return 单词

 箭头函数的美,最能体现在连续箭头。当外层函数被调用的时候,将返回内层的函数。调用的时候可以加两层圆括号

 

箭头函数中的 this 是定义时所处的上下文,和如何调用无关!

 比如下面有一个 obj 对象,这个对象的 b 方法是用箭头函数写的。这个箭头函数所在的最外层函数体是 window 域。

所以 this 不管 b 函数如何被调用,一律是 window 对象

var a = 9;
var obj = {
    a : 1 ,
    b : () => {   // 箭头
        console.log(this.a);
    }
}
obj.b(); //9  这里不能用 node 解析, window 对象

甚至call、apply失效:

 

this 在箭头函数中是固定的,这个性质是我们应该防止的、加以警惕的;而不是利用的

箭头函数有几个使用注意点

(1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。

(2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。

(3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。

(4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数。

 

 6.2 bind()

bind表示给一个函数定死上下文,而无论它如何被调用。

 

比如下面有一个函数 fun,函数体输出 this.a。

我们在后面有一个 .bind() 语句,彻底将 fun 函数的上下文定死了,就是 obj 对象。

无论 fun 函数如何被调用,一律上下文是 obj 对象。

 

function fun(){
    console.log(this.a);
}

//这是一个对象
var obj = {
    a : 233 ,
    b : 886
}

//这是另一个对象
var another = {
    a : 6666666666666
}

//定死上下文为obj对象
fun = fun.bind(obj);

fun();                        //233
fun.call(another);            //233,call失效了
fun.apply(another);         //233,apply失效了

bind 和 call 和 apply 有什么区别?

l  bind 不调用函数,call 和 apply 会调用函数。

l  bind 能绑死上下文,call 和 apply 是临时的。

 

6.3 默认参数

在形参列表中可以加等号运算符,表示参数的默认参数,当我们没有传入这个参数的时候,

将自动使用这个默认参数

 

const mianji = (r , pi = 3.14) => {
    return pi * r  * r;
}

console.log(mianji(10 , Math.PI));    //传了第二个参数,就是用第二个参数
console.log(mianji(10));                //没有第二个参数,将用默认的3.14

 

 

 七 字符串, 正则改变

 建议大家可以自己学习: 字符串, 正则

``是新增的定界符,可以和  ${变量} 使用,减少连字符的使用:

 

 

八 类的改变

现在可以用 class 关键字来定义一个类,语法:

虽然增加了 class 关键字,但是 JS 中还是没有类!JS 中仍然是简单的“基于对象”原型链的模式来模拟类的。

也就是说,机理没有变化!

 

ES6 中简化了类的继承:

 

class People{
    constructor(name , age , sex){
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    changge(){
        console.log("我是一个" + this.name + "今年" + this.age + "岁啦!!");
    }
}

class Student extends People{
    constructor(name , age , sex , xuehao , banji){
        super(name , age , sex);     //调用超类的构造器
        this.xuehao = xuehao;
        this.banji = banji;
    }

    kaoshi(){
        console.log(`${this.name}在考试`);
    }
}

var xiaohua = new Student("小花",12,"女",10001,"1班");
xiaohua.changge();
xiaohua.kaoshi();

 

 

九 promise 对象   未完。。。

 

posted @ 2019-01-01 17:40  Bijou  阅读(568)  评论(0编辑  收藏  举报