理解JavaScript(7):ES6

ES6

  现在前端开始已经普遍使用es6进行开发,但是浏览器还不能很好的支持es6语法。

ES6开发环境搭建
1.安装node(https://nodejs.org/zh-cn/
2.新建项目目录,在该目录路径下运行运行 npm init
3.命令行npm install
4.运行npm install –save-dev babel-cli
5.配置packages.json文件,在scripts中配置 “bulid”:”babel src -d lib”
6.该命令是将src所有使用es6语法的js脚本通过babel编译为浏览器能识别的js脚本,并放在src同级的lib目录中。如果在该目录的命名行中运行 babel+空格+文件路径,就是单独编译该文件,并会在命令行输出,当然也可以配置编译结果的输出目录。具体请看http://babeljs.io/docs/en/babel-cli/
7.当然这样我们就能使用es6,但是在实际开发过程中,这样做会异常麻烦,我们需要配合其他开发工具一起使用,我一般使用webpack,其基本配置可以参考babel官网 (http://babeljs.io/setup.html#installation

ES6重点语法

  • 模块化
import util from './util1.js';
impor {fn1, fn2} from './util2.js';
console.log(util1); // {a: 100}
fn1(); // 1
fn2(); // 2

// util1.js
export default {
    a: 100
}
// util2.js
export function fn1 () {
    console.log(1);
}
export function fn2 () {
    console.log(2);
}
// export 引用时要加上{}
// 一个js文件中可以有多个export
// 一个js文件中只能有一个export default
// babel 编译ES6语法,模块化可用webpack和rollup,期待前端早日实现模块化的统一
  • class
// 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());
// ---------------------------------------------
// ES6
class MathHandle {
    constructor (x, y) {
        this.x = x;
        this.y = y;
    }
    add () {
        return this.x + this.y;
    }
}
const m = new MathHandle(1, 2);
console.log(m.add());

typeof MathHandle // function
MathHandle === MathHandle.prototype.consturctor; // true
m.__proto__ === MathHandle.prototype // true
// 实际是语法糖形式,看起来和实际原理不一样,为了和java C#形式上看起来相同,不利于新手了解JavaScript原理

  继承

class Animal {
    constructor (name) {
        this.name = name;
    }
    eat () {
        console.log(`S{this.name} 吃肉`);
    }
}
class Dog extends Animal {
    constructor (name) {
        // super可以当做函数使用,可以当做对象使用,ES6要求子类的构造函数必须执行一次super,super作为对象指向父类的原型,在静态方法中使用指向父类
        super(name); 
        this.name = name;
    }
    say () {
        console.log(`${this.name} say`);
    }
}
class Dog = new Dog('哈士奇');
dog.say(); // 哈士奇 say
dog.eat(); // 哈士奇 吃肉
  • promise
    promise由jQuery中的deferred的对象演化而来,deferred对象是不安全的,执行转态可以在外部通过reslove和reject方法在外部改变deferred详解
// 需引入jQuery
function waitHandle () {
    var dtd = $.Deferred();
    var wait = function (dtd) {
        var task = function () {
            console.log("执行完成");
            dtd.resolve(); //表示异步任务执行完成
            // dtd.reject() 失败只能是一个;
        };
        setTimeout(task, 2000);
        return dtd;
    };
    return wait(dtd);
}
var w = waitHandle();
w.then(function () {
    console.log('ok 1');
}, function () {
    console.log('err 1')
}).then(function () {
    console.log('ok 2');
}, function () {
    console.log('err 2')
});
// 还有w.done w.fail...
w.reject(); // 没有这一句,2s后输出:执行完成,ok 1,ok 2;加上这一句后输出err 1,err 2,2s后输出:执行完成;不同的人合作会造成很大的麻烦

// 为了安全我们需要在返回jquery中的promise对象
function waitHandle () {
    var dtd = $.Deferred();
    var wait = function (dtd) {
        var task = function () {
            console.log("执行完成");
            dtd.resolve(); 
            // dtd.reject();
        };
        setTimeout(task, 2000);
        return dtd.promise(); //唯一修改的地方,但会promise对象
    };
    return wait(dtd);
}
var w = waitHandle();
w.then(function () {
    console.log('ok 1');
}, function () {
    console.log('err 1')
}).then(function () {
    console.log('ok 2');
}, function () {
    console.log('err 2')
});
w.reject(); // Uncaught TypeError: w.reject is not a function 执行完成 ok 1 ok 2 
// 外边只能监听不能改变执行状态

// promise标准的基本语法
// new一个Promise对象,传入一个函数,有两个参数resolve,reject,最后返回promise对象实例
function loadImg (src) {
    var promise = new Promise(function (resolve, reject) {
        var img = document.createElement('img');
        img.onload = function () {
            resolve(img);
        }
        img.onerror = function () {
            reject()
        }
        img.src = src; 
    });
    return promise;
}
var src = "http://www.imooc.com/static/img/index/logo_new.png";
var result = loadImg(src);
result.then(function (img) {
    console.log(img.width);
    return img;
}, function () {
    console.log("失败");
}).then(function (img) {
    console.log(img.height);
});
// 异常捕获 成功只传入成功后执行的函数,一个函数
var src = "http://www.imooc.com/static/img/index/logo_new.png";
var result = loadImg(src);
// var result1 = loadImg(src);
result.then(result.then(function (img) {
    console.log(img.width);
    return img;
    // return result1;就可以实现多个promise串联执行
}).then(function (img) {
    console.log(img.height);
}).catch(function () {
    console.log("fail");
});
// 多个promise全部完成后执行 Promise.all([result, result1,...], function(){}),其中一个Promise完成就执行,promise.race([result, result1,...], function(){})
  • let、const
// JS 只能通过var定义变量
var i = 10;
i = 100;
var j = 20;
j = 100;
// ES6
// const 定义常量,定义的量不能改变值
let i = 10;
i = 100;
const j = 20;
j = 200; // 报错
  • 多行字符串、模板变量
// JS
var name = 'zhangsan', age = 20, html = '';
html += '<div>';
html += '  <p>' + name + '</p>';
html += '  <p>' + age + '</p>';
html += '</div>'
// 前面写起来复杂,用ES6就简单的多不容易出错,效果一样
let name = 'zhangsan', age = 20;
let html = `<div>
              <p>${name}</p>
              <p>${age}</p>
            </div>`;
  • 解构赋值
// JS
var obj = {a: 100, b: 200};
var a = obj.a, b = obj.b;

var arr = ['xx', 'yy', 'zz'];
var x = arr[0];
// ES6
let obj = {a: 100, b: 200};
let {a, b} = obj; // a = 100, b = 200
let {c} = obj // c为undefined 对象解构,变量名和对象属性名对应
let arr = ['xx', 'yy', 'zz'];
let [x, y, z] = arr; // x = 'xx'...
let [m] = arr // m = 'xx' 数组解构,按照数组中的索引与变量一一对应
  • 块级作用域
// JS没有块级作用域,所以要注意,写var item 要放在方面
var obj = {a: 100, b: 200};
for (var item in obj) {
    console.log(item); // a, b
}
console.log(item); // b

// ES6
const obj = {a: 100, b: 200};
for (let item in obj) {
    console.log(item); // a, b
}
console.log(item); // undifined
  • 函数默认参数
// JS 
function (a, b) {
    if (b == null) {
        b = 0;
    }
}
// ES6
function (a, b = 0) {
}
// 这两者效果相同
  • 箭头函数
// 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;
});

  箭头函数是普通js的补充,箭头函数中的this指向的是函数体之外的最新的js

function fn () {
    console.log('real', this); // {a: 100}
    var arr = [1, 2, 3];
    // JS
    arr.map(function (item) {
        console.log('js', this); // window对象
        return item + 1;
    });
    // 箭头函数
    arr.map(item => {
        console.log('es6', this); // {a: 100}
        return item + 1;
    });
}
fn.call({a: 100});
  • es7中的async/await
    es7中的async/await是promise的扩展,是最直接的同步写法,then只是将callback拆分了
// promise的写法,waitHandle就是promise中的函数
var w = waitHandle();
w.then(function () {
    console.log('ok 1');
}, function () {
    console.log(err);
});
// async 和 await写法,想要在函数体中使用await,函数必须使用async标识,await后面必须跟一个promise实例,需要用babel-polyfill
const load = async function () {
    const result1 = await loadImg(src1);
    console.log(result1);
    const result1 = await loadImg(src2);
    console.log(result2);
}
load();
// async 和 await使用了promise,可以使用完全同步的写法
// promise 和 async/await改变不了JS单线程的本质
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值