# 初探Class、继承、Promise 及 ES6 常用功能
# Class - 语法糖
- Class 在语法上更贴合面向对象的写法
- Class 实现继承更加易读、易理解
- 更易于写 java 等后端语言的使用
- 本质还是语法糖,使用 prototype
# ES5中的写法
获取实例对象的原型对象Object.getPrototypeOf(m2)
判断实例与构造函数的原型对象是否有关系MathHandle2.prototype.isPrototypeOf(m2)
function MathHandle2(x, y) {
this.x = x
this.y = y
}
MathHandle2.prototype.add = function () {
return this.x + this.y
}
var m2 = new MathHandle2(1,3)
console.log(m2.add())
console.log(m2.__proto__ === MathHandle2.prototype) //true
// 获取实例对象的原型对象Object.getPrototypeOf()
console.log(Object.getPrototypeOf(m2) === MathHandle2.prototype) //true
// 判断实例与构造函数的原型对象是否有关系isPrototypeOf()
console.log(MathHandle2.prototype.isPrototypeOf(m2)) //true
# ES6中的写法
对象实例的隐式原型(属性)指向构造函数的原型对象m.__proto__ === MathHandle.prototype
构造函数的原型对象的constructor属性指回了构造函数本身MathHandle.prototype.constructor === MathHandle
class MathHandle { // 构造函数
constructor(x, y) {
this.x = x
this.y = y
}
add() {
return this.x + this.y
}
}
const m = new MathHandle(1, 3)
console.log(m.add()) //4
// 对象实例的隐式原型(属性)指向构造函数的原型对象
console.log(m.__proto__ === MathHandle.prototype) //true
// 构造函数的原型对象的constructor属性指回了构造函数本身
console.log(MathHandle.prototype.constructor === MathHandle) //true
# 继承
# prototype
function Animal() {
this.eat = function() {
console.log('Animal eat')
}
}
function Dog() {
this.bark = function() {
console.log('Dog bark')
}
}
// 绑定原型,实现继承
Dog.prototype = new Animal()
var hashiqi = new Dog()
hashiqi.eat() // Animal eat
hashiqi.bark() // Dog bark
# extends
class Animal {
constructor(name) {
this.name = name
}
eat() {
console.log('Animal eat!' + this.name)
}
}
class Dog extends Animal {
constructor(name) {
super(name)
this.name = name
}
bark() {
console.log('Dog bark!' + this.name)
}
}
const hashiqi = new Dog('哈士奇')
hashiqi.eat()
hashiqi.bark()
# Promise
- new Promise 实例,而且要 return
- new Promise 时要传入函数,函数有 resolve、reject 两个函数
- 成功时执行 resolve(),失败时执行 reject()
- then 监听结果
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 src1 = 'https://img3.mukewang.com/5c611772085966af06000338-240-135.jpg'
var src2 = 'https://img2.mukewang.com/5c6b7cff08d6895906000338-240-135.jpg'
var result1 = loadImg(src1)
var result2 = loadImg(src2)
result1.then(function(img) {
console.log('第一张图片', img.src)
return result2 //串联操作
}).then(function(img) {
console.log('第二张图片', img.src)
}).catch(function(ex) { // 统一捕获错误信息
console.log(ex)
})
// Promise.all 接受一个 promise 对象的数组,待全部完成之后,统一执行 success
var result3 = loadImg(src1)
var result4 = loadImg(src2)
Promise.all([result3, result4]).then(function(data) {
console.log(data)
})
// Promise.race 接受一个包含多个 promise 对象的数组,只要有一个完成,就执行 success
Promise.race([result3,result4]).then(function(data) {
console.log('race:', data)
})
# ES6常用功能
- let const
- 多行字符串、模板变量
- 解构赋值
- 块级作用域
- 函数默认参数
- 箭头函数
// let const
let i = 10;
i = 20; // Uncaught SyntaxError: Identifier 'i' has already been declared
const j = 100
j = 20 // Uncaught TypeError: Assignment to constant variable.
// 多行字符串、模板变量
const name = 'yangtao', age = 27;
const html = `
<div>
<p>${name}</p>
<p>${age}</p>
</div>`;
// 结构赋值
const obj = {a: 100, b: 200}
const {a, b} = obj
// 等同于(对象按照属性)
var obj = {a: 100, b: 200}
var a = obj.a,
b = obj.b;
const arr = ['xxx', 'yyy', 'zzz']
const [x, z] = arr
// 等同于(数组按照索引)
var arr = ['xxx', 'yyy', 'zzz']
var x = arr[0],
z = arr[1];
// 块级作用域
const myObj = {a: 1, b: 2}
for(let item in obj) {
console.log(item)
}
console.log(item)
// 等同于
var myObj = { a: 1, b: 2 };
for (var _item in obj) {
console.log(_item);
}
console.log(item);
// 函数参数
function num(a,b=0) {
}
// 等同于
function num2(a) {
var b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
}
// 箭头函数
const myarr = [1,3,4]
myarr.map(item => item + 1)
myarr.map((item, index) => console.log(item, index))
// 等同于
var myarr = [1, 3, 4];
myarr.map(function (item) {
return item + 1;
});
myarr.map(function (item, index) {
return console.log(item, index);
});
// this指向很诡异
function fn() {
console.log('real', this) // real {a: 10}
var arr = [1,2,3];
arr.map(function(item) {
console.log(this) // window
})
}
fn.call({a: 10})
// 使用箭头函数修改
function fn() {
console.log('real', this) // real {a: 10}
var arr = [1,2,3];
arr.map(item => console.log(this)) // {a: 10}
}
fn.call({a: 10})
// 等同于
function fn() {
var _this = this;
console.log('real', this); // real {a: 10}
var arr = [1, 2, 3];
arr.map(function (item) {
return console.log(_this);
}); // {a: 10}
}
fn.call({ a: 10 });
# 关于 JS 众多模块化标准
- 没有模块化
- AMD成为标准,require.js(也有CMD)
- 前端打包工具,是node.js模块化可以被使用
- ES6出现,想统一现在所有模块化标准
- nodejs积极支持,浏览器尚未统一
# 模块化
- 语法:import export(注意有无default)
- 环境:babel编译 ES6 语法,模块化可用 webpack 和 rollup
- 扩展:对模块化标准统一的期待
# Rollup
- rollup 功能单一,webpack 功能强大
- 参考设计原则和《Linux/Unix设计思想》
- 工具要尽量功能单一,可集成,可扩展
- gulp + rollup