ES6入门随笔

  • 开发环境已普及
  • 浏览器环境支持不好(需要开发环境编译)
  • 开发环境如何使用+重点语法的掌握

问题:

  • 模块化,开发环境如何打包
  • Class与普通构造函数
  • Promise
  • 总结ES6常用功能

模块化与打包

  1. export与import语法

    /* util1.js*/
    export default {
        a: 1
    }
    
    /* util2.js */
    export function fun1() {}
    export function fun2() {}
    
    /* index.js */
    import util1 from './util1'
    import {fun1, fun2} from 'util2'
    
  2. 模块化

    • 开发环境 - babel语法解析,将ES6语法解析成浏览器可识别的低层次语法
      • node环境安装

      • 创建项目工程文件:es-test

      • 在项目根目录下,npm init

      • npm install —save-dev babel-core babel-preset-env babel-preset-latest

      • 在项目根目录下,创建.babelrc文件,这是babel的配置文件

        // .babelrc
        {
          "presets": ["env", "latest"],
          "plugins": []
        }
        
      • npm install —global babel-cli

      • babel —version,可以查看当前版本号

      • 创建./src/index.js

        .
        └── src
            └── index.js
        
        // index.js
        [1, 2, 3].map(item => item + 1)
        
      • 运行 babel ./src/index.js

        // 控制台打印
        [1, 2, 3].map(function (item) {
          return item + 1;
        });
        
    • 开发环境 - webpack处理模块化
      • npm install webpack babel-loader —save-dev

      • 配置 webpack.config.js

        module.exports = {
            entry: "./src/index.js",
            output: {
                path: __dirname,
                filename: "./build/bundle.js"
            },
            module: {
                rules: [{
                    test: /\.js?$/,
                    exclude: /(node_modules)/,
                    loader: "babel-loader"
                }]
            }
        }
        
      • 配置 package.json 中的 scripts

        "scripts": {
            "start": "webpack",
            "test": "echo \"Error: no test specified\" && exit 1"
          },
        
      • 运行 npm start

    • 开发环境 - rollup
      • npm init
      • npm i —save-dev rollup rollup-plugin-node-resolve rollup-plugin-babel babel-plugin-external-helpers babel-preset-latest
      • 配置 .babelrc
      • 配置 rollup.config.js
    • Webpack、rollup比较
      • rollup功能单一,webpack功能强大
      • 参考设计原则和《Linux/Unix设计思想》
      • 工具尽量功能单一,可集成,可扩展
  3. 总结

    • 语法: import export(注意有无 default)
    • 环境: babel 编译 ES6 语法,模块化可用webpack 和 rollup
    • 扩展:说一下自己对模块化标准统一的期望
  4. 时间轴

    • 没有模块化
    • AMD 成为标准,require.js (也有CMD)
    • 前端打包工具,是nodejs模块化可以被使用
    • ES6出现,想统一现在的所有模块化标准
    • nodejs积极支持,浏览器尚未统一
    • 可以自造lib,但不能自造标准

Babel7 的配置与使用

Babel是将ES6语法转换成浏览器可识别的向后兼容版本的JS代码。
从低版本到babel7,有几项变化:

  • 不再支持不在维护中的 Node 版本:0.10、0.12、4、5;
  • 使用 @babel 命名空间,因此 babel-core 就变成了 @babel/core;
  • 移除(并停止发布)任何年度预设(preset-es2015 等),@babel/preset-env 取代了对这些内容的需求 ;
  • 移除“Stage” 预设(@babel/preset-stage-0 等),同时移除了 @babel/polyfill 中的提议;
  • 重命名了某些包:任何 TC39 提议插件现在都是 -proposal 而不是 -transform,所以 @babel/plugin-transform-class-properties 变成了 @babel/plugin-proposal-class-properties;
  • 针对某些面向用户的包(例如 babel-loader、@babel/cli 等)在 @babel/core 中引入 peerDependency;
  1. Babel-upgrade

    babel-upgrade 是一个用于自动升级的新工具,具体可见https://github.com/babel/babel-upgrade

    建议直接在git仓库上运行 npx babel-upgrade,或者使用 npm i babel-upgrade -g 进行全局安装。若是想修改文件,可是使用参数 --write--install

    npx babel-upgrade --write --install
    
  2. 安装配置

    npm install --save-dev @babel/core @babel/cli @babel/preset-env
    npm install --save @babel/polyfill 
    // 注意 --save 选项而不是 --save-dev,因为这是一个需要在源代码之前运行的 polyfill。
    

    配置Babel,你可以使用.babelrc文件方式,同时Babel 7 引入了 babel.config.js,

    babel.config.js 的配置解析方式与.babelrc 不同。它始终会解析该文件中的配置,而不会从每个文件向上查找,直到找到配置为止。这样就可以利用 overrides 特性。

    • .babelrc

      {
        "presets": [
          ["@babel/env", {
            "targets": {
              "edge": "17",
              "firefox": "60",
              "chrome": "67",
              "safari": "11.1"
            },
            "useBuiltIns": "usage",
            "debug": true // 可以看到打包的文件。
          }
          ]
        ],
        "plugins": []
      }
      
    • babel.config.js

      const presets = [
        ["@babel/env", {
          targets: {
            edge: "17",
            firefox: "60",
            chrome: "67",
            safari: "11.1"
          },
          useBuiltIns: "usage"
        }]
      ];
      
      var env = process.env.NODE_ENV;
      module.exports = {
        presets,
        plugins: [
          env === "production" && "babel-plugin-that-is-cool"
        ].filter(Boolean)
      };
      

      使用 overrides进行选择性配置

      module.exports = {
        presets: [
          // defeault config...
        ],
        overrides: [{
          test: ["./node_modules"],
          presets: [
            // config for node_modules
          ],
        }, {
          test: ["./tests"],
          presets: [
            // config for tests
          ],
        }]
      };
      

      有些应用程序需要针对测试、客户端代码和服务器代码使用不同的编译配置选项,通过这种方式就不需要在每个文件夹下创建.babelrc 文件了。

      我们使用的是 env preset,其中有一个 "useBuiltIns" 选项,当设置为 "usage" 时,实际上将应用上面提到的最后一个优化,只包括你需要的 polyfill。

      例如Promise.resolve().finally()会变成这个require("core-js/modules/es.promise.finally"); Promise.resolve().finally();如果我们没有将 env preset 的 "useBuiltIns" 选项的设置为 "usage" ,就必须在其他代码之前 require 一次完整的 polyfill。

    • 运行./node_modules/.bin/babel src --out-dir lib将所有代码从 src 目录编译到 lib

    我们使用 @babel/cli 从终端运行 Babel,@babel/polyfill 来实现所有新的 JavaScript 功能,useBuiltIns:entry 会根据target环境加载polyfill,需要手动import polyfill,不能多次引入。@babel/preset-env会将把@babel/polyfill根据实际需求打散,只留下必须的。做的只是打散。仅引入有浏览器不支持的polyfill。这样也会提高一些性能,减少编译后的polyfill文件大小。env preset 只包含我们使用的功能的转换,实现我们的目标浏览器中缺少的功能。

Class 和普通构造函数的区别

  1. JS 构造函数

    // 构造函数
    function MathHandle(x, y) {
        this.x = x
        this.y = y
    }
    // 原型扩展
    MathHandle.prototype.add = function() {
        return this.x + this.y
    }
    // 实例化
    var m = new MathHAndle(1, 2)
    console.log(m.add()) // 3
    typeof MathHandle // function
    MathHandle/prototype.constructor === MathHandle // true
    m.__proto__ === MathHandle.prototype // true
    
  2. Class 基本语法

    class Ad extends Rect.Component {
        constructor(props) {
            super(props)
            this.state = {
                data: []
            }
        }
        componentDidMount() {}
        render() {
            return (
                <div>hello world</div>
            )
        }
    }
    
  3. 语法糖

    class MathHandle {
        // ...
    }
    
    typeof MathHandle // function
    MathHandle/prototype.constructor === MathHandle // true
    m.__proto__ === MathHandle.prototype // true
    
  4. 继承

    // 动物
    function Animal() {
        this.eat = function() {
            console.log('animal eat')
        }
    }
    // 狗
    function Dog() {
        this.dark = function() {
            console.log('dog dark')
        }
    }
    
    Dog.prototype = new Animal()
    var d = new Dog()
    
    class Animal {
        constructor(name) {
            this.name = name
        }
        eat() {
            console.log(`${this.name} eat`)
        }
    }
    
    class Dog extends Animal {
        constructor(name) {
            super(name)
            this.name = name
        }
        say() {
            console.log(`${this.name} say`)
        }
    }
    
    var dog = new Dog('hashiqi')
    dog.say()
    dog.eat()
    
  5. 总结

    • class 在语法上更加贴合面向对象的写法
    • class 实现继承更加易读、易理解
    • 更易于写Java等后端语言的使用
    • 本质还是语法糖,使用 prototype

Promise

function loadImg(src, callback, fail) {
    var img = document.createElement('img')
    img.onload = function () {
        callback(img)
    }
    img.onerror = function () {
        fail()
    }
    img.src = src
}

var src= 'http://www.imooc.com/static/img/index/logo_new.png'
loadImg(src, function (img) {
    console.log(img.width)
}, function () {
    console.log('failed')
})
function loadImg(src) {
    return new Promise(function (resolve, reject) {
        var img = document.createElement('img')
        img.onload = function () {
            resolve(img)
        }
        img.onerror = function () {
            reject()
        }
        img.src= src
    })
}
var src = 'http://www.imooc.com/static/img/index/logo_new.png'
var result = loadImg(src)
result.then(function (img) {
    console.log(img.width)
}, function () {
    console.log('failed')
})
result.then(function (img) {
    console.log(img.height)
})

其他常用功能

  1. let/const

    // js
    var i = 10
    i = 100
    
    // es6
    let i = 10
    i = 100
    const j = 20
    j = 200 // 报错
    
  2. 多行字符串/模板变量

    // js
    var name = 'an'
    var html + = '<div>'
    html += name
    html += '</div>'
    
    //es6
    var name = 'an'
    const html = `<div>${name}</div>`
    
  3. 解构赋值

    //js
    var obj = {a:1, b: 2}
    obj.a
    var arr = [1, 2, 3]
    arr[0]
    
    //es6
    const obj = {a:1, b: 2}
    const {a, b} = obj
    a
    const arr = [1, 2, 3]
    const [a, b, c] = arr
    x
    
  4. 块级作用域

    //js
    var obj = {a: 1, b: 2}
    for (var item in obj) {
        console.log(item)
    }
    console.log(item) // output: b
    
    // es6
    const obj = {a: 1, b: 2}
    for (let item in obj) {
        console.log(item)
    }
    console.log(item) // output: undefined
    
  5. 函数默认参数

    // js
    function(a, b) {
        if (b == null) b = 0
    }
    
    // es6
    function(a, b=0) {}
    
  6. 箭头函数

    //js
    var arr = [1, 2, 3]
    arr.map(function(item) {
        return item + 1
    })
    
    // es6
    const arr = [1, 2, 3]
    arr.map(item =>item + 1)
    arr.map((item, index) => {
        console.log(index)
        return item +1
    })
    
    function fun() {
        console.log(this) // output: {a: 100}
        var arr = [1, 2, 3]
        // js
        arr.map(function(item) {
            console.log(this) // output: window
        	return item + 1
        })
        // 箭头函数:对普通JS的补充
        arr.map(item =>{
            console.log(this) // output: {a: 100}
            return item + 1
        })
    }
    fun.call({a: 100})
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值