笔记只是部分摘录
1.课程概述
包括:高级基础,框架原理,app混合开发
技术:JS、ES6、虚拟DOM、vue、React、hybrid
知识点介绍:
高级基础:
ES6常用语法:Class、Module、Promise等
原型高级应用:结合jQuery和zepto源码
异步全面讲解:从原理到jQuery再到Promise
框架原理:
虚拟DOM:存在价值,如何使用,diff算法
vue:MVVM,vue响应式,模板解析,渲染
React:组件化,JSX,vdom,setState
对比:有主见,自圆其说
涉及知识点:es6、异步、原型、vdom、mvvm、组件化、hybrid和其他
es6:模块化的使用和编译环境、Class和JS构造函数的区别、Promise的用法、ES6其他常用功能
异步:什么是单线程和异步有何关系、什么是event-loop、目前JS解决异步的方案有哪些、如果只用jQuery如何解决异步、Promise的标准、async/await的使用
原型:原型如何实际应用、原型如何满足扩展
vdom:什么是vdom为何要用vdom、vdom如何使用核心函数有哪些、了解diff算法吗
MVVM:之前使用jQuery和现在使用vue或React框架的区别、你如何理解MVVM、vue如何实现响应式、vue如何解析模板、介绍vue的实现流程
组件化:对组件化的理解、JSX是什么、JSX和vdom什么关系、简述React和setState、简述自己如何比较React和vue
其他:如何写博客、如何做开源
2.ES6
问题
ES6模块化如何使用,开发环境如何打包
Class和普通构造函数有何区别
Promise的基本使用和原理
总结一下ES6其他常用功能
3.ES6模块化
export和import
//export
export default{
a:100
}
export function fn1(){
console.log('fn1');
}
export function fn2(){
console.log('fn2');
}
let myName="laowang";
let myAge=90;
let myfn=function(){
return "我是"+myName+"!今年"+myAge+"岁了"
}
export {
myName,
myAge,
myfn
}
//import
import util1 from './util1.js'
console.log(util1)
import {fn1,fn2} from './util2.js'
fn1()
fn2()
import {myfn,myAge,myName} from "./test.js";
console.log(myfn());//我是laowang!今年90岁了
console.log(myAge);//90
console.log(myName);//laowang
babel使用
参考之前文章:https://blog.csdn.net/u014465934/article/details/85306244
下面介绍两种方式使用babel:
1.直接使用.babelrc文件和package.json配置babel环境
开发环境:
1.电脑有node环境,运行npm init
2.安装bable中的一些依赖
npm install babel-core babel-present-es2015 babel-preset-latest --save-dev
3.创建.baberrc文件
{
"presets":["es2015","latest"],
"plugins":[]
}
4.安装babel-cli
npm install --global babel-cli
5.创建./src/index.js
[1,2,3].map(item => item+1);
6.运行 babel ./src/index.js。
再说明下,我们经常看见到babel src -d lib
的意思是把src文件夹下的文件都转译,转译后的文件放到lib目录下。
附注说明:如果你不想生成.babelrc文件,你可以在你的package.json文件中对babel进行配置。
看下面代码:
{
"name": "es6",
"version": "1.0.0",
"description": "",
"main": "arrow.js",
"scripts": {
"build": "babel src -d lib --comments=true"
},
"babel":{
//babel选项
"presets":["es2015"],
"comments":false
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"babel-cli": "^6.24.1",
"babel-loader": "^7.1.1",
"babel-preset-env": "^1.6.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"webpack": "^3.2.0"
}
}
2.Webpack中使用babel
1.安装Webpack插件
npm install webpack babel-loader --save-dev
2.配置webpack.config.js
3.配置package.json中的scripts
4.运行 npm start
webpack 模块化开发
1.模块化打包,减少网络请求
2.配合 babel,转换 es6 语法
3.配合 less、sass等,对 css 进行预处理
4.可处理、压缩图片
5.代码压缩
6.代码检查
7. 等等
package.json文件主要是描述description信息和配置,webpack.config.js是说明使用方法。
package.json
{
"name": "es6-webpack",
"version": "1.0.0",
"description": "es6 webpack init project",
"main": "index.js",
"scripts": {
"watch": "webpack --watch",
"start": "webpack-dev-server --open"
},
"repository": {
"type": "git",
"url": "git+https://github.com/cucygh/es6-webpack.git"
},
"author": "",
"license": "MIT",
"bugs": {
"url": "https://github.com/cucygh/es6-webpack/issues"
},
"eslintConfig": {
"root": true,
"parserOptions": {
"ecmaVersion": 2017
},
"extends": [
"mysticatea",
"mysticatea/modules"
],
"plugins": [
"html"
],
"env": {
"browser": false
},
"globals": {
"applicationCache": false,
"atob": false,
"btoa": false,
"console": false,
"document": false,
"location": false,
"window": false
},
"parser": "babel-eslint"
},
"eslintIgnore": [
"node_modules",
"webpack.config.js"
],
"babel": {
"presets": [
"env"
]
},
"homepage": "https://github.com/cucygh/es6-webpack#readme",
"devDependencies": {
"babel-core": "^6.26.0",
"babel-eslint": "^8.0.3",
"babel-loader": "^7.1.2",
"babel-preset-env": "^1.6.1",
"clean-webpack-plugin": "^0.1.17",
"eslint": "^3.19.0",
"eslint-plugin-babel": "^4.1.2",
"eslint-plugin-html": "^4.0.1",
"extract-text-webpack-plugin": "^3.0.2",
"html-loader": "^0.5.1",
"html-webpack-plugin": "^2.30.1",
"webpack": "^3.10.0",
"webpack-dev-server": "^2.9.5"
},
"dependencies": {
"babel-polyfill": "^6.26.0",
"eslint-config-mysticatea": "^12.0.0"
}
}
webpack.config.js
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry: ['babel-polyfill','./index.js'],
devServer: {
contentBase: './dist',
hot: true,
compress: true,
port: 9000,
clientLogLevel: "none",
quiet: true
},
module: {
loaders: [
{
test: /\.html$/,
loader: 'html-loader'
}, {
test: /\.js$/,
loader: 'babel-loader'
}]
},
plugins: [
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({template: './index.html'}),
new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin()
],
output: {
filename: 'index.js',
path: path.resolve(__dirname, 'dist')
}
};
总结:
关于babel的知识点大概就这些。
1.babel常用的转译器是babel-preset-env。
2.常用的配置选项是plugins和presets
3.常用的使用场景是在webpack中
babel配置一般所需要的依赖:
babel-loader、babel-core、babel-preset-env、babel-polyfill、babel-runtime和babel-plugin-transform-runtime
babel-loader:在import或加载模块时,对es6代码进行预处理,es6语法转化为es5语法。
babel-core:允许我们去调用babel的api,可以将js代码分析成ast(抽象语法树),方便各个插件分析语法进行相应的处理.
babel-preset-env:指定规范,比如es2015,es2016,es2017,latest,env(包含前面全部)
babel-polyfill:它效仿一个完整的ES2015+环境,使得我们能够使用新的内置对象比如 Promise,静态方法比如Array.from 或者 Object.assign, 实例方法比如 Array.prototype.includes 和生成器函数(提供给你使用 regenerator 插件)。为了达到这一点, polyfill 添加到了全局范围,就像原生类型比如 String 一样。
babel-runtime babel-plugin-transform-runtime:与babel-polyfill作用一样,使用场景不一样。
Webpack4配置参考文章:http://www.imooc.com/article/287156
关于babel更多参考:
https://zhuanlan.zhihu.com/p/43249121
https://www.kancloud.cn/digest/babel/217112
https://juejin.im/post/5c0f39526fb9a04a0e2d09da
https://juejin.im/post/59ec657ef265da431b6c5b03
http://www.ruanyifeng.com/blog/2016/01/babel.html
https://segmentfault.com/a/1190000008159877
https://www.babeljs.cn/docs/usage
https://www.babeljs.cn/setup#installation
模块化总结
针对ES6模块化,我们需要使用babel对ES6进行编译,针对babel使用我们可以用webpack和rollup模块化工具。
4.ES6中Class
Class和普通构造函数有何区别
JS构造函数、Class基本语法、语法糖、继承(JS构造函数实现继承、Class实现继承)
JS构造函数:
构造函数:如用函数用来初始化(使用new运算符)一个新建的对象,我们称之为构造函数(constructor)
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())
关于构造函数和普通函数区别:https://segmentfault.com/a/1190000008615288
Class语法:
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());
class实质上是构造函数的语法糖,JS本身并没有class。(语法糖:本质是一样的,但是另外一种方式更加易懂,易学)
在构造函数/Class中下面输入输出都是一样的:
typeof MathHandle //function(所以class本质还是函数)
MathHandle.prototype.constructor === MathHandle //true (MathHandle(构造函数)显式原型是MathHandle.prototype)
m.__proto__ === MathHandle.prototype //true (实例m(对象实例)隐式原型通过m.__proto__获得,是MathHandle(构造函数)的显式原型,即MathHandle.prototype)
上面说明,Class中一些类型和原型知识是和构造函数一样的,所以Class实质上是构造函数的语法糖。
继承
ES5中继承(通过原型完成):
function Animal(){
this.eat = function(){
console.log();
}
}
function Dog(){
this.bark = function(){
console.log();
}
}
Dog.prototype = new Animal()
var hashiqi = new Dog()
ES6(1.子类加上extends 2.constructor里面加上super)继承:
class Animal {
constructor(name){
this.name = name
}
eat(){
alert(this.name + ' eat')
}
}
class Dog extends Animal{
constructor(name){
super(name)
}
say(){
alert(this.name + ' say')
}
}
const dog = new Dog('哈士奇')
dog.say()
我们还要注意一个问题,关于constructor指向的修正的问题,先看下面代码。
Dog.prototype = new Animal()
但是这样子写的话,dog 的构造函数就成 animal 的构造函数了,如下:
Dog.prototype.constructor == Animal.prototype.constructor == Animal
所以,指向了Animal构造函数,所以一般加上下面代码进行修正:
Dog.prototype.constructor = Dog
还可以参考:https://blog.csdn.net/u014465934/article/details/94666349
里面关键一句话是:constructor始终指向的是创建本身的构造函数,所以Dog.prototype.constructor指向Animal,按照这个思路理解也可以。
5.ES6中Promise
一个Promise使用实例:
function loadImg(src) {
const imgUrl = new Promise((resolve, reject) => {
let img = document.createElement('img')
img.onload = () => resolve(img)
img.onerror = () => reject()
img.src = src
})
return imgUrl;
}
const src = 'https://www.imooc.com/static/img/index/logo.png'
loadImg(src).then((img)=> {
console.log(img.width) // 成功打印 200
return img;
}).then((img) => {
console.log(img.height) // 打印高度
}).catch(error => {
console.log(`${error}`)
})
回调函数/Promise/async await顺序对比讲解:
//1.callback 方式获取一个文件的内容
function getFileContent(fileName, callback) {
const fullFileName = path.resolve(__dirname, 'files', fileName)
fs.readFile(fullFileName, (err, data) => {
if (err) {
console.error(err)
return
}
callback(
JSON.parse(data.toString())
)
})
}
// 测试 callback-hell(回调地狱)
getFileContent('a.json', aData => {
console.log('a data', aData)
getFileContent(aData.next, bData => {
console.log('b data', bData)
getFileContent(bData.next, cData => {
console.log('c data', cData)
})
})
})
//2.利用Promise解决回调地狱
// 用 promise 获取文件内容
function getFileContent(fileName) {
const promise = new Promise((resolve, reject) => {
const fullFileName = path.resolve(__dirname, 'files', fileName)
fs.readFile(fullFileName, (err, data) => {
if (err) {
reject(err)
return
}
resolve(
JSON.parse(data.toString())
)
})
})
return promise
}
getFileContent('a.json')
.then(aData => {
console.log('a data', aData)
return getFileContent(aData.next)
})
.then(bData => {
console.log('b data', bData)
return getFileContent(bData.next)
})
.then(cData => {
console.log('c data', cData)
})
//3.使用async await解决
function getFileContent(fileName) {
const promise = new Promise((resolve, reject) => {
const fullFileName = path.resolve(__dirname, 'files', fileName)
fs.readFile(fullFileName, (err, data) => {
if (err) {
reject(err)
return
}
resolve(
JSON.parse(data.toString())
)
})
})
return promise
}
async function readFileData() {
// 同步写法
try {
const aData = await getFileContent('a.json')
console.log('a data', aData)
const bData = await getFileContent(aData.next)
console.log('b data', bData)
const cData = await getFileContent(bData.next)
console.log('c data', cData)
} catch (err) {
console.error(err)
}
}
readFileData()
// async await 要点:
// 1. await 后面可以追加 promise 对象,获取 resolve 的值
// 2. await 必须包裹在 async 函数里面
// 3. async 函数执行返回的也是一个 promise 对象
// 4. try-catch 截获 promise 中 reject 的值
Promise问题解答:
更多参考:
https://developers.google.com/web/fundamentals/primers/promises
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise
6.ES6常用功能
let/const
多行字符串/模板变量
解构赋值
块级作用域
函数默认参数
箭头函数
//多行字符串/模板变量
const name = 'zhangsan',age= 20;
const html = `