### ES6模块化如何使用,开发环境如何打包
* 模块化的基本语法
* 开发环境配置
* 关于js众多模块化标准
#### 语法
~~~
export default {
a:100
}
~~~
~~~
export function fn1(){
alert()
}
export function fn2(){
alert()
}
~~~
~~~
import util1 from "./util1.js";
import{fn1,fn2} from "./util2.js"
console.log(util1);
fn1();fn2();
~~~
export default :只默认输出一个
export好几个:{}(大括号引用)
### 开发环境babel
ES6中的新语法,用到浏览器中,**需要一个编译的过程**,因为ES6的新语法在**浏览器中没有一个全面的支持**,因此开发环境中要在浏览器中使用的话要有一个转换的过程,将**新语法转化成旧版本标准的语法**,因此用到**babel**
babel:js编译器(转换器)
* 电脑有node环境,运行npm init
* **npm install --save-dev babel-core babel-preset-es2015 babel-preset-latest**
淘宝镜像--registry=https://registry.npm.taobao.org
* 创建`.babelrc`文件(.表示隐藏文件)
~~~
{
"presets":['es2015','latest'],
"plugins":[]
}
~~~
* npm install --global babel-cli
全局安装 babel-cli(管理员模式打开)
* babel --version(可以使用babel命令)
* 创建./src/index
* 箭头函数(ES6)
* 运行**babel src/index.js**
### 开发环境 webpack
babel可以将ES6语法解析成es5语法,语法层面
但针对模块化,(相互引用关系,多层次引用关系),babel不行
webpack:**可进行模块化处理**,但webpack不只是用来模块化
* npm install --save-dev webpack babel-loader
* 配置webpack.config.js
新建webpack.config.js文件
(webpack是nodejs实现的,符合commonJS规范)
~~~
module.exports = {
//入口文件
entry:‘./src/indx.js’,
//出口配置
output:{
//当前目录
path:__dirname,
filename:'./build/bundle.js'//会自动创建
},
//定义的一些模块
module:{
//定义规则
rules:[{
//所有的js除了node-modules,通过babel-loader编译
test:/\.js?$/,//.js结尾
exclude:/(node_modules)/,//除了这个目录(第三方代码),
loader:'babel-loader'
}]
}
}
~~~
* 配置package.json中的scripts
~~~
“scripts”:{
"start": "webpack",
"test":''"
}
~~~
* 运行npm start
其实就是运行webpack,对js代码用babel进行编译,生成到bundle.js中
### 开发环境 rollup
相比于webpack,**更高级**
**vue,react都是用rollup打包**
rollup非常小,尽量简化打包后输出文件的大小
对于庞大的环境,可更优化
1. npm init
2. npm i --save-dev rollup rollup-plugin-node-resolve rollup-plugin-babel babel-plugin-external-helpers babel-preset-latest babel-core
3. 配置 .babelrc
~~~
{
"presets":[
["latest",{"modules":false}]
],
"plugins":["external-helpers"]
}
~~~
4. 配置rollup.config.js
~~~
import babel from 'rollup-plugin-babel';
import resolve from "rollup-plugin-node-resolve"
export default{
entry:'src/index.js',
format:'umd',//格式umd即兼容页面引入script,又兼容amd,commonjs
plugins:[
resolve(),
babel({
exclude:'node_modules/**'
})
],
dest:'build/bundle.js'
}
~~~
5. 修改package.json的scripts
~~~
"scripts":{
"start":'rollup -c rollup.config.js'
"test":''
}
~~~
6. 运行npm start
webpack打包127行,rollup打包30多行
roll up:打包之后代码基本不会改,你的还是你的,不会有太多冗余代码
* **rollup功能单一**(打包模块化),**webpack功能强大**(学习成本高)
* 参考设计原则,**单一值原则**(做成一个单一功能就行,没必要更好,更快,更强,更全面,最好一个东西只做一件,做好就行)(越简单越好,不用功能全面)
* **工具要尽量功能单一,可继承,可扩展**
* wangEditor用的gulp+rollup(开源工具)
### 关于js众多模块化标准
1. 没有模块化
2. **AMD成为标准**,require.js(也有CMD,但用的比较少)
require,define这些语法定义,**完成模块化的编写**,AMD成为标准,
完善的前端工程体系
**前端需要掌握AMD标准**
3. 前端打包工具,使得nodejs模块化可以被使用 gulp,webpack(commonJS模块化可以被使用,commonJS是后端标准,通过后端打包工具打包成前端可识别的方式)
4. ES6出现,想统一现在所有模块化标准
5. nodejs积极支持,浏览器尚未统一(服务端可以使用)
浏览器不敢把es6放开用,因为比较危险,在服务端用es6写没有问题,但浏览器端需要通过工具把es6打包成es5
6. 你可以自造lib,但不要自造标准
### 问题解答
1. 语法:import export (注意有无default)
2. 环境:babel编译ES6语法的核心工具,模块化可用webpack和rollup
3. 扩展:模块化统一的期望
*****
### Class和普通构造函数有何区别
1. js构造函数
2. Class基本语法
3. 语法糖
4. 继承
react
~~~
class Ad extend React Component{
constructor(props){
super(props);
this.state={
data:[]
}
},
render(){
return( <div>hello imooc</div>)
},
componentDidMount(){}
}
~~~
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());
typeof MathHandle //"function"
MathHandle === MathHandle.prototype.constructor;//true
m.__proto__=== MathHandle.prototype//true
~~~
2. Class基本语法
更加统一化
~~~
//名字后直接大括号
class MathHandle{
//参数 new的时候传的参数
constructor(x,y){
this.x = x;
this.y = y;
}
add(){
return this.x +this.y
}
}
const m = new MathHandle(1,2);
m.add();
typeof MathHandle //"function"
MathHandle === MathHandle.prototype.constructor;//true
m.__proto__=== MathHandle.prototype//true
~~~
**typeof MathHandle //"function"
MathHandle === MathHandle.prototype.constructor;//true
m.\__proto__=== MathHandle.prototype//true**
prototype(显示原型)\__proto__(隐式原型)
3. 语法糖
class完全符合js构造函数原理,因此,class本身是语法糖
写法本质是一样的,但第二种比第一中更加简单易懂
~~~
class MathHandle {
}
typeof MathHandle //"function"
MathHandle === MathHandle.prototype.constructor;//true
~~~
**class**:本身是一个语法糖,是一个函数
**typeof MathHandle //"function"**
class的原型的constructor是构造函数本身
**MathHandle === MathHandle.prototype.constructor;**
这种语法糖,看起来和实际原理不一样的东西,不赞同
形式上强行模仿 java,C#却失去了它的本性和个性
原型的继承
4. 继承
~~~
function Animal(){
this.eat = function(){
}
}
function Dog(){
this.bark = function(){
}
}
Dog.prototype = new Animal();
var hashiqi = new Dog();
~~~
**Dog.prototype = new Animal();**
~~~
class Animal{
constructor(name){
this.name = name;
}
eat(){
console.log(this.name+':eat')
}
}
class Dog extends Animal{
constructor(name){
super(name);
}
say(){
console.log(this.name+':say')
}
}
const dog = new Dog('哈士奇');
dog.say();
dog.eat();
~~~
**class Dog extends Animal**
**super(name)**:被继承的class的constructor
class继承:提高阅读体验,与java很像
### **问题解答**
1. Class在语法上更加贴合面向对象的写法(发展方向)
2. Class实现继承更加易读,易理解,入门容易,学习成本低
3. 更易于写java等后端语言的使用
4. **本质还是语法糖,使用prototype继承**
*****
### **Promise的基本使用**
* Callback hell
异步加载:
~~~
function loadImg(src, callback, fail){
var img = document.createElement('img');
img.onload = function(){
callback(img)
}
img.onerror = function(){ fail() }
img.src = src;
}
var src="...";
loadImg(src,function(img){
console.log(img.width)
},function(){console.log('fail')})
~~~
* Promise语法
~~~
function loadImg(src){
const 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="xxx";
var result = loadImg(src);
result.then(function(img){
console.log(img.width);
},function(){
console.log('fail')
});
result.then(function(height){console.log(img.height)});
~~~
**const promise = new Promise()**
**return promise**
### 问题解答
1. new Promise实例,而且要return
2. new Promise时要传入函数,函数有resolve和reject两个
3. 成功时执行resolve(),失败时执行reject()
4. then监听结果
*****
### 总结ES6其他常用功能
模块化,class,promise
二八原则:20%的功能满足80%的需求
箭头函数
1. let/const
2. 多行字符串/模板变量(js拼接 **反引号 ${}**)(多行中完整的字符串)(字符串必须单行单行写)
3. 解构赋值(server模块导出一个对象,可用解构后去需要的属性)
4. 块级作用域(之前js没有块级作用域)
5. 函数默认参数
6. 箭头函数(this彻底解决函数指向全局window对象的问题)
7. 扩展运算符(...)
8. ES module
**`对象中的扩展运算符(...)用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中`**
~~~
let bar = { a: 1, b: 2 }; let baz = { ...bar }; // { a: 1, b: 2
//相当于
let baz = Object.assign({}, bar);
let bar = {a: 1, b: 2};
let baz = {...bar, ...{a:2, b: 4}}; // {a: 2, b: 4}
~~~
**可以将数组转换为参数序列**
用于替换`es5`中的`Array.prototype.slice.call(arguments)`写法
~~~
function add(x, y) { return x + y; } const numbers \= \[4, 38\]; add(...numbers) // 42
~~~
详解:
1. let/const
常量值不可改,报错
2. 多行字符串/模板变量
~~~
const name = "guo",age =19;
const html = `<div>
<p>${name}</p>
</div>`
console.log(html);
~~~
3. 解构赋值
代码要易读,再精简不易读也不行
~~~
const obj = {a:10,b:20,c:30};
const {a,c} = obj;
const arr =[19,290,39];
const [x,y,z] = arr;
~~~
4. 块级作用域
~~~
const obj = {a:19,b:09}
for(let item in obj){
}
console.log(item);//undefiedn
~~~
5. 默认参数
~~~
function(a, b=0){}
var b = arguments.length>1&&arguments[1]!==undefined?argument[1]:0;
~~~
~~~
function fn(a,b){
if(b == null){b=0;}
}
~~~
6. 箭头函数
~~~
arr.map(item=>item+1)
arr.map((item,index)=>{
})
~~~
~~~
function fn(){
console.log('real',this);//{a:100}
var arr = [1,3];
arr.map(function(){
console.log(this)//window
});
arr.map((item,index)=>{
console.log(this);//{a:100}
})
}
fn.call({a:100})
~~~
.call:执行时,把{a:100}对象,变成this(强制变成)
- 空白目录
- 双樾
- JS基础知识
- JS-WEB-API
- 开发环境
- 运行环境
- ES6
- 原型
- 异步
- 虚拟dom
- mvvm
- 组件化和React
- hybrid
- 其他
- 补充
- 技巧
- 快乐动起来呀
- css
- 掘金小册子
- js基础知识
- ES6知识点
- JS异步
- JS进阶知识
- 思考题
- DevTools Tips
- 浏览器基础知识
- 浏览器缓存机制0
- 浏览器渲染原理
- 安全防范知识点0
- 从V8中看JS性能优化0
- 性能优化琐碎事
- Webpack性能优化0
- 实现小型打包工具0
- React和Vue
- Vue生命周期
- vue基础知识点
- Vue响应式
- vue高级
- React基础
- Vue.js技术解密
- 准备工作
- 数据驱动
- new Vue()
- vue实例挂载
- 组件化
- 深入响应式原理
- 编译
- 扩展
- Vue Router
- Vuex