关于ES6
- 开发环境已经普及使用
- 浏览器环境却支持不好(需要开发环境编译)
- 内容很多,重点了解常用语法
- 面试:开发环境的使用,重点语法的掌握
问题
- ES6模块化如何使用,开发环境如何打包?
模块花的基本语法
/* util1.js */
export default {
a:100
}
/* util2.js */
export function fn1() {
alert('fn1')
}
export function fn2() {
alert('fn2')
}
/* index.js */
import util1 from './util1.js'
import { fn1, fn2 } from './util1.js'
console.log(util1)
fn1()
fn2()
开发环境的配置
电脑有node环境,运行npm init
npm install --save-dev babel-loader @babel/core
/*webpack.config.js*/
module: {
rules: [
{ test: /\.js$/, exclude: /node_modules/, loader: "babel-loader" }
]
}
创建.babelrc文件
npm install @babel/preset-env --save-dev
/*.babelrc中的配置*/
{
"presets": ["@babel/preset-env"] // ES6转ES5语法
}
我们不仅需要用@babel/preset-env做语法的转换,还需要把缺失的变量或者函数,补充到低版本浏览器,
怎么补充呢,需要借助@babel/polyfill把这些缺失的变量或者函数,补充到低版本浏览器
npm install --save @babel/polyfill
关于JS众多模块化标准
一开始没有没有模块化
AMD成为标准,require.js(也有国内的CMD,很少用)
前端打包工具,使得nodejs模块化(commonJS模块规范)可以被使用
ES6出现,想统一现在所有模块化标准
nodejs积极支持,浏览器尚未统一
你可以自早lib(库),但是不要自造标准
总结
语法: import export 注意有无(default)
环境:babel编译ES6语法,模块化可用webpack,rollup
扩展:说一下自己对模块化标准统一的期待
- class和普通构造函数的有何区别?
js构造函数
function Animal() {
this.name = 'name'
}
Animal.prototype.say = function(){
alert(this.name)
}
const cat = new Animal()
cat.say()
Class语法
class Animate {
constructor() {
this.name = 'cat'
}
say(){
alert(this.name)
}
}
const cat = new Animal()
cat.say()
语法糖
// 所谓的语法糖,就是两种写法本质是一样的,但是第二种写法更加简单,更加易写。
class Animate { ... }
typeof Animate // function
Animate === Animate.prototype.constructor // true
cat.__proto__ === Animate.prototype // true
class继承
class Animate {
constructor() {
this.name = 'cat'
}
eat() {
console.log('eat something')
}
}
class Dog extends Animate {
constructor(name,color) {
super(name)
this.color = color
}
say() {
console.log(this.name)
}
}
const dog= new Dog('taidi')
dog.eat()
dog.say()
class总结:
class 在语法上更加贴合面向对象的写法
calss实现继承,更加易读,易理解
更易于写java等后端语言的使用
本质还是语法糖,使用prototype
- Promise的基本使用和原理
Promise的出现就是为了解决 callback hell(回调地狱)
// 不用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 = 'https://www.imooc.com/static/img/index/logo-recommended.png'
loadImg(src, function (img) {
console.log(img.width)
}, function () {
console.log('加载失败')
})
// 用promise改造上边的函数
function loadImg(src) {
const p = new Promise((resolve, reject) => {
var img = document.createElement('img')
img.onload = function () {
resolve(img)
}
img.onerror = function () {
reject(new Error('图片加载失败'))
}
img.src = src
})
return p
}
var src = 'https://www.imooc.com/static/img/index/loo-recommended.png'
loadImg(src).then((img) => {
console.log(img.width)
return img
}).then((img) => {
console.log(img.height)
}).catch((err) => {
console.error(err)
})
promise基本语法总结
new Promise实例,然后return
new Promise()接受函数作为参数,函数有resolve,reject两个参数
成功是执行resolve(),失败时执行reject()
then监听结果
- 总结ES6的常用功能
1. let/const
let 定义变量,可以被重新赋值
const 定义常量,不能重新赋值
// js
var a = 10
a = 20
//ES6
let b = 30
b = 40 // 正确
const c = 50
c = 60 // 报错
2. 多行字符串/模板变量 ``
//js
var name = 'zhangsan', age = 20, html = '';
html += '<div>';
html += '<p>' + name + '</p>';
html += '<p>' + age + '</p>';
html += '</div>';
//ES6
const name = 'zhangsan', age = 20
const html = `
<div>
<p>${name}</p>
<p>${age}</p>
</div>
`
3. 解构赋值
var arr1 = ['a', 'b', 'c']
console.log(obj1.a, obj1.b, obj1.c) // 10,20,30
console.log(arr1[0]) //a
const obj2 = {
a: 10,
b: 20,
c: 30
}
const {a , b} = obj2
console.log(a, b) //10 20
let [o, p, q] = [1, 2, 3];
console.log(o) // 1
console.log(p) // 2
console.log(q) // 3
4. 块级作用域
var obj = {
a: 10,
b: 20,
c: 30
}
for (var item in obj) {
console.log(item) // a,b,c
}
console.log(item) // c
const obj2 = {
a: 10,
b: 20,
c: 30
}
for (let item in obj2) {
console.log(item) // a,b,c
}
console.log(item) // item is not defined
5. 函数默认参数
// js
function fn(a, b) {
if (a == null) {
a = 0
}
}
// ES6
function fn(a = 0, b) {
}
6. 箭头函数
// js
var arr1 = [1, 2, 3]
var res = arr1.map(function (item) {
return item+1
})
console.log(res) //[2, 3, 4]
// ES6
const arr2 = [1, 2, 3]
// 如果函数只有一个参数,并且函数体中只有一行,可以这么写
const res2 = arr2.map(item => item + 1)
// 当然如果函数有2个参数,并且函数体多余1行的化,要这么写
const res3 = arr2.map((item, index) => {
console.log(index)
return item *2
})
console.log(res2) // [2, 3, 4]
console.log(res3) //[2, 4, 6]
function fn() {
console.log(this) // {a:100]}
var arr1 = [1, 2, 3]
var res = arr1.map(function (item) {
console.log('js' + this) // window JS里比较坑的地方,明明是在map函数里的this结果还是指向window
return item+1
})
const arr2 = [4,5,6]
const res2 = arr2.map(item => {
console.log('ES6',this) // {a:100} 箭头函数就完美的解决了上边函数里的this的指向问题
item + 1
}
)
}
fn.call({a:100}) // 我们通过call将fn的this指向 {a:100}