ES6 的基础教程 一、介绍 二丶兼容性 三丶变量数据类型 四丶函数 五丶解构赋值 六丶数组的扩展 七丶字符串扩展 八丶ES6的面向对象 九丶json 十丶异步处理 十一丶闭包 十二丶模块化

1.历史

  1. ECMAScript和JavaScript
    • ECMA是标准,JS是实现
      • 类似于HTML5是标准,IE10、Chrome、FF都是实现
      • 换句话说,将来也能有其他XXXScript来实现ECMA
    • ECMAScript简称ECMA或ES
    • 目前版本
      • 低级浏览器主要支持ES 3.1
      • 高级浏览器正在从ES 5过渡到ES 6
  2. 历史版本
时间 ECMA JS 解释
1996.11 ES 1.0 JS稳定 Netscape将JS提交给ECMA组织,ES正式出现
1998.06 ES 2.0 ES2正式发布
1999.12 ES 3.0 ES3被广泛支持
2007.10 ES 4.0 ES4过于激进,被废了
2008.07 ES 3.1 4.0退化为严重缩水版的3.1
因为吵得太厉害,所以ES 3.1代号为Harmony(和谐)
2009.12 ES 5.0 ES 5.0正式发布
同时公布了JavaScript.next也就是后来的ES 6.0
2011.06 ES 5.1 ES 5.1成为了ISO国际标准
2013.03 ES 6.0 ES 6.0草案定稿
2013.12 ES 6.0 ES 6.0草案发布
2015.06 ES 6.0 ES 6.0预计发布正式版
JavaScript.next开始指向ES 7.0

二丶兼容性

http://kangax.github.io/compat-table/es5/
http://kangax.github.io/compat-table/es6/

ES6(ES2015)

支持IE10+、Chrome、FireFox、移动端、NodeJS

不支持可以:

1.在线转换

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <script src="browser.js" charset="utf-8"></script>
    <script type="text/babel">
    let a=12;
    let b=5;

    alert(a+b);
    </script>
  </head>
  <body>
  </body>
</html>

2.NodeJS编译

安装node 并且执行node init -y

npm i @babel/core @babel/cli @babel/preset-env

添加脚本

"scripts":{
    "build":"babel src -d test"
}

添加.babelrc——声明preset

{
  "presets": ["@babel/preset-env"]
}

ES7(ECMA 2016)

**求幂

Array.includes()

ES8(ECMA 2017)

await/async

ES9(ECMA 2018)

rest/spread
异步迭代
Promise.finally()
正则

三丶变量数据类型

var

1.可以重复声明

2.无法限制修改

3.没有块级作用域

if (true) {
var a = 12;
}
alert(a)

let (声明变量)

不能重复声明,可以修改,支持块级作用域

let a=12;
let a=123;
alert(a);//SyntaxError: redeclaration of let a
if (true) {
let a = 12;
}
alert(a);//ReferenceError: a is not defined

const(声明常量)

不能重复声明,不能修改,支持块级作用域

const a = 12;
a = 123;
alert(a);//TypeError: invalid assignment to const `a'

作用域

1.传统函数级

2.ES6块级

语法块

{}

if(){

}

for(){

}

{

}

Object数据类型

使用对象字面量表示法

var person = {
  name : "Micheal",
  age : 24
  //不要使用箭头函数
  hello(){
  	console.log("nigao");
  }
};


使用对象字面量表示法

var person = new Object();
person.name = "Micheal";
person.age = 24;


定义对象的属性

let name="yancy";
let age =20;
let es6={
	name,
	age
}


Object.is()

基本数据类型

console.log("具体值:", Object.is("hello", "hello")); //具体值: true


引用数据类型

console.log("具体值:", Object.is({}, {})); //具体值: false


Object.assign()

用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。

const a = { a: 1 };
const b = { b: 2 };
const c = { c: 3 };
let d = Object.assign(a, b, c)
console.log(d);


Object.keys(),Object.values(),Object.entries()

let obj = { a: 1, b: 2, c: 3 };
for (let key of Object.keys(obj)) {
  console.log(key);
}
for (let value of Object.values(obj)) {
  console.log(value);
}
for (let [key, value] of Object.entries(obj)) {
  console.log([key, value]);
}


Symbol数据类型

表示独一无二的值。

  • 不能用了new
  • Symbol()返回一个唯一的值,常用来作为对象的私有属性
let sym = Symbol(124);

console.log(sym); ////Symbol(124)
console.log(typeof sym);// symbol


//返回唯一的值
let s1 = Symbol();
let s2 = Symbol('another symbol');
let s3 = Symbol('another symbol');

console.log(s1 === s2); // false
console.log(s2 === s3); // false


应用

使用Symbol来作为对象属性名(key)

使用Symbol来替代常量3

Set

存储无重复值的有序列表

let set1 = new Set();
set.add(1);
set.add('1');
set.delete('1');
set.has(1);//true
console.log(set.size);//2
set.clear();


遍历

  • keys():返回键名的遍历器
  • values():返回键值的遍历器
  • entries():返回键值对的遍历器
  • forEach():使用回调函数遍历每个成员
  • for...of:直接遍历每个成员

WeakSet

成员是对象

垃圾回收机制不用考虑存在于WeakSet中

不能迭代(没有 for of keys vaules forEach size

let ws = new WeakSet();


Map

键值对的集合

const m = new Map();
const obj = { p: ' Hello world' };
console.log(m.set(obj, ' content'));
//Map { { p: ' Hello world' } => ' content' }
console.log(m.get(obj)); //content
console.log(m.has(obj)); //true
console.log(m.delete(obj)); //true
console.log(m.has(obj)); //false


常用方法

set  返回整个map结构
get  找不到返回undefined
delete
has
clear


keys
values
entries
forEach
for of


WeakMap

  • WeakMap只接受对象作为键名(null除外),不接受其他类型的值作为键名。
  • WeakMap的键名所指向的对象,不计入垃圾回收机制。

Itertor遍历器

遍历器(lterator)就是这样一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署terator接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。

  • 为各种数据结构,提供一个统一的、简便的访问接口;
  • 使得数据结构的成员能够按某种次序排列;
  • ES6创造了一种新的遍历命令for..of循环,lterator接口主要供for..of消费。
  • Array
  • Object
  • Map
  • Set
  • String
  • NodeList
  • TypedArray

四丶函数

函数默认值

  • 简洁;
  • 阅读代码的人,可以立刻意识到哪些参数是可以省略的,不用查看函数体或文档;
  • 有利于将来的代码优化,即使未来的版本在对外接口中,彻底拿掉这个参数,也不会导致以前的代码无法运行。

参数默认值不是传值的,而是每次都重新计算默认值表达式的值。也就是说,参数默认值是惰性求值的。

function log(x, y = 'World') {
  console.log(x, y);
}
console.log('Hello');
console.log('Hello', 'China');


参数默认值可以与解构赋值的默认值,结合起来使用。

function foo({ x, y = 5 }) {
  console.log(x, y);
}
foo({}); //undefined 5
foo({ x: 1 }); //1 5
foo({ x: 1, y: 2 }); //1 2
//  foo(); //TypeError: Cannot destructure property `x` of 'undefined' or 'null'.
//上面代码只使用了对象的解构赋值默认值,没有使用函数参数的默认值。只有 当函数 foo 的参数是一个对象时,变量 x 和 y 才会通过解构赋值生成。如果函数 foo 调用时没提供参数,变量 x 和 y 就不会生成,从而报错。通过提供函数 参数的默认值,就可以避免这种情况。 


function foo({ x, y = 5 } = {}) {
  console.log(x, y);
}
foo(); //undefined 5
//上面代码指定,如果没有提供参数,函数 foo 的参数默认为一个空对象。 通过解构赋值取得默认值。 



function Point(x = 1, y = 2) {
  this.x = x;
  this.y = y;
}
const p = new Point();
console.log(p.x, p.y);//1 2


区别

function m1({ x = 0, y = 0 } = {}) {
  console.log(x, y);
  return [x, y];
}

function m2({ x, y } = { x: 0, y: 0 }) {
  console.log(x, y);
  return [x, y];
}
m1(); //0 0
m2(); //0 0

m1({ x: 3, y: 8 }); //3 8
m2({ x: 3, y: 8 }); //3 8

m1({ x: 3 }); //3 0
m2({ x: 3 }); //3 undefined

m1({ z: 3 }); //0 0
m2({ z: 3 }); //undefined undefined


函数的 length 属性

指定了默认值以后,函数的 length 属性,将返回没有指定默认值的参数个数。 也就是说,指定了默认值后,length 属性将失真。


箭头函数(可以修复this)

只是简写

function 名字(参数){

}
(参数)=>{

}


  • 如果,有且仅有1个参数,()也可以省
  • 无参数 多参数 括号不能省略
  • 如果,有且仅有1条语句-return,{}可以省(json一般不简写)
  • 多行语句 {} 不能省略
    let show=a=>a*2;
    alert(show(12));


函数的 rest参数

用于获取函数的多余参数,这样就 不需要使用 arguments 对象了。rest 参数搭配的变量是一个数组,该变量将多 余的参数放入数组中。

function show(a, b, ...args){}

function show(a, b, ...args, c){
alert(args);
}

show(12, 15, 8, 9, 20, 21, 90);//Uncaught SyntaxError: Rest parameter must be last formal parameter


Rest Parameter必须是最后一个

扩展运算符(...)

将一个数组转为用逗号分隔的参数序列,或将一个类数组转换成真正的数组。

  let arr = [1, 2, 3];
      show(...arr);
      //...arr
      //1,2,3
      //show(1,2,3);
      function show(a, b, c) {
        alert(a);
        alert(b);
        alert(c);
      }


    let arr1=[1,2,3];
    let arr2=[5,6,7];

    let arr=[...arr1, ...arr2];

    alert(arr);


展开后的效果,跟直接把数组的内容写在这儿一样

    let a;
    let arr=[1,2,3];

    a=...arr;//Uncaught SyntaxError: Unexpected token ...

    alert(a);


严格模式

ES2016 做了一点修改,规定只要函数参数使用了默认值、

解构赋值、或者扩展 运算符,那么函数内部就不能显式设定为严格模式,否则会报错。

'use strict'

  • 全局严格模式
  • 放在无参数的函数里

name属性

函数的 name 属性,返回该函数的函数名。

var f = function fun() {}
console.log(f.name); //fun


五丶解构赋值

1.左右两边结构必须一样
2.右边必须是个东西
3.声明和赋值不能分开(必须在一句话里完成)

数组:

    let [a,b,c]=[1,2,3];
    console.log(a, b, c);


	//...表达式	
	let [ head,... tail]=[1,2,3,4]; 
	console. log(head, tail);//[2,3,4]


	//默认值
	let [ foo=true]=[]; 
	console. log(foo);//true

	let [bar, foo] = [1];
	console.log(bar, foo); //1 undefined

	let [x, y = 'b'] = ['a'];
	console.log(x, y);//a b

	let [x, y = 'b'] = ['a', undefined];
	console.log(x, y); //a b

	let [x = 1] = [null];
	console.log(x); //null

	function f() {
 	  console.log(' aaa');
	  return 10;
	}
	let [x = f()] = [99];
	console.log(x);//99

function f() {
  console.log(' aaa');
  return 10;
}
let [x = f()] = [];
console.log(x); //aaa 10


//有length属性会自动转换


let [foo, a] = "string";
console.log(a); //t



json:

    let {a, c, d}={a: 12, c: 5, d: 6};
    console.log(a, c, d);


    let [{a, b}, [n1, n2, n3], num, str]=[{a: 12, b: 5}, [12,5,8], 8, 'cxzcv'];

    console.log(a,b,n1,n2,n3,num,str);


注意

    let [a,b]={a: 12, b: 45};

    console.log(a,b);//Uncaught TypeError: {(intermediate value)(intermediate value)} is not iterable



    let {a,b}={12,5};

    console.log(a,b);//Uncaught SyntaxError: Unexpected token ,


    let [a,b];
    [a,b]=[12,5];
    console.log(a,b);//Uncaught SyntaxError: Missing initializer in destructuring declaration


对象

  • 没有次序
  • 与属性同名
  let { foo: foo, bar: bar } = { foo: "aaa", bar: "bbb" };
  console.log(foo, bar);//aaa bbb


  //没有对象名
  let { foo, bar } = { foo: "aaa", bar: "bbb" };
  console.log(foo, bar);//aaa bbb


let obj = { first: ' hello', last: ' world' };
let { first: h, last: w } = obj;
console.log(h, w); // hello  world


//默认值
var { x = 3 } = {};
console.log(x); //3
var { x, y = 5 } = { x: 1 };
console.log(x, y);//1 5
var { x: y = 3 } = {};
console.log(x, y);//1 3

var { x = 3 } = {};
console.log(x); //3
var { y = 3 } = { y: undefined };
console.log(y); //3
var { z = 3 } = { z: null };
console.log(z); //null


//分行 块级做域不行
let a, b;
[a, b] = [1, 2];
console.log(a, b);//1 2

//圆括号可以 尽量不要用
let a, b;
({ a, b } = { a: 1, b: 2 });
console.log(a, b);


字符串:

const [a, b, c, d, e] = 'hello';
console.log(a, b, c, d, e); //h e l l o


//长度属性
let { length: len } = 'hello';
console.log(len); //5


布尔值

let { toString: s } = false;
console.log(s === Boolean.prototype.toString); //true


函数参数的解构赋值

function add([x, y]) {
  return x + y;
}
res = add([1, 2]);
console.log(res); //3


let n = [
  [1, 2],
  [3, 4]
].map(([a, b]) => a + b);
console.log(n); //[3,7]


//默认值
function move({ x = 0, y = 0 } = {}) {
  return [x, y];
}
console.log(move({ x: 3, y: 8 })); //[3,8]
console.log(move({ x: 3 })); //[3,0]
console.log(move({})); //[0,0]
console.log(move()); //[0,0]


应用

//交换变量
let x = 1,
  y = 3;
[x, y] = [y, x];
console.log(x, y);//3 1


//返回多个值
function example() {
  return [1, 2, 3];
}
let [a, b, c] =
example();
console.log(a, b, c);//1 2 3

function example() {
  return {
    foo: 1,
    bar: 2
  };
}
let { foo, bar } =
example();
console.log(foo, bar);//1 2


//统一参数变量
function f([x, y, z]) {
  console.log(x, y, z);
};
f([1, 2, 3]);//1 2 3

function f({ x, y, z }) {
  console.log(x, y, z);
};
f({ z: 3, y: 2, x: 1 });//1 2 3


//提取JSON
let jsonData = { id: 42, status: "OK", data: [867, 5309] };
let { id, status, data: number } =
jsonData;
console.log(id, status, number); //42 OK [ 867, 5309 ]


//函数默认值



//遍历map
const map = new Map();
map.set(' first', ' hello');
map.set(' second', ' world');
//获取键名
for (let [key, value] of map) { console.log(key + "is" + value) }; // firstis hel1o secondis world


//模块的制定输入


六丶数组的扩展

map 映射

返回一个新数组;如没有return,就相当于forEach,所以,在使用map时,一定要有return。

一个对一个
[12, 58, 99, 86, 45, 91]
[不及格, 不及格, 及格, 及格, 不及格, 及格]

let arr=[19, 85, 99, 25, 90];
//用item分别存储
let result=arr.map(item=>item>=60?'及格':'不及格');

alert(score);
alert(result);


[45, 57, 135, 28]
[
{name: 'blue', level: 0, role: 0},
{name: 'zhangsan', level: 99, role: 3},
{name: 'aaa', level: 0, role: 0},
{name: 'blue', level: 0, role: 0},
]

let arrMap = [1, 2, 3, 4];
let resMap = arrMap.map((item, index, arrMap) => {
  return item * 2;
});
console.log(resMap); //[2,4,6,8]


reduce 汇总

接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。

reduce() 可以作为一个高阶函数,用于函数的 compose。

一堆出来一个
算个总数
[12, 8000000, 599999] => 80060011

 let arr=[12,69,180,8763];
//tmp为前面的和 12+69  item=180
let result=arr.reduce( (tmp, item, index)=>{
      //alert(tmp+','+item+','+index);
      return tmp+item; //tmp为前面的和 12+69  item=180
});

alert(result);


算个平均数
[12, 59, 99] => 56.67

  let arr=[12,69,180,8763];

    let result=arr.reduce(function (tmp, item, index)=>{
      if(index!=arr.length-1){ //不是最后一次
        return tmp+item;
      }else{                    //最后一次
        return (tmp+item)/arr.length;
      }
    });

    alert(result);


filter 过滤器

过滤掉不满足条件的数据。

    let arr=[12,5,8,99,27,36,75,11];

    let result=arr.filter(item=>item%3==0);

    alert(result);


    let arr=[
      {title: '男士衬衫', price: 75},
      {title: '女士包', price: 57842},
      {title: '男士包', price: 65},
      {title: '女士鞋', price: 27531}
    ];

    let result=arr.filter(item=>item.price>=10000);

    console.log(result);


forEach 循环(迭代)

let arr=[12,5,8,9];

arr.forEach((item,index)=>{
alert(index+': '+item);
    });


<button onclick="numbers.forEach(myFunction)">点我</button>
<p ></p>
<script>
demoP = document.getElementById("demo");
var numbers = [4, 9, 16, 25];
function myFunction(item, index) {
    demoP.innerHTML = demoP.innerHTML + "index[" +    index + "]: " + item + "<br>"; 
}
</script> 


every每一个

数组里全部元素满足条件,则返回true

  • 用于检测数组所有元素是否都符合指定条件(通过函数提供)
    • 如果数组中检测到有一个元素不满足,则整个表达式返回 false
    • 如果所有元素都满足条件,则返回 true。
var numbers = [5, 9, 11, 25, 11];
var res = numbers.every((item, index) => {
    return item % 2 == 1;
});
alert(`every:${res}`); //every:ture


判断是否全部为奇数

some一个

数组里某一元素满足条件,则返回

  • 用于检测数组中的元素是否满足指定条件(函数提供)。
  • 会依次执行数组的每个元
    • 如果有一个元素满足条件,则表达式返回true
    • 如果没有满足条件的元素,则返回false。
var numbers = [5, 9, 2, 25, 11];
var res = numbers.some((item, index) => {
    return item % 2 == 1;
});
alert(`some:${res}`); //some:ture


判断一个为偶数数

for…of

一个循环来迭代可迭代的对象。

用来替代 for...in 和 forEach() ,并支持新的迭代协议。

for...of 允许遍历 Arrays(数组), Strings(字符串), Maps(映射), Sets(集合)等可迭代的数据结构等。

let arr2 = ["apple", "pear", "strawbeey"];
for (let val of arr2) {
  console.log(` for (let val of arr2): ${val}`);
} // for (let val of arr2): apple
//for (let val of arr2): pear
//for (let val of arr2): strawbeey


entries()

返回一个数组的迭代对象,该对象包含数组的键值对 (key/value)。

for (let item of arr2.entries()) {
  console.log(item);
} //[ 0, 'apple' ]
//[1, 'pear']
//[2, 'strawbeey']
for (let [key, value] of arr2.entries()) {
  console.log(key, value);
}//0 apple 1 pear 2 strawbeey


Array.from()

具有length属性 可遍历对象 转换为数组

let str = "hello";
let strEx = [...str];
let strFrom = Array.from(str);

console.log(strEx); //["h","e","1","1",o"]
console.log(strFrom); //["h","e","1","1",o"]


//数组输入参数
function foo() {
  const args = [...arguments];
  const args1 = Array.from(arguments);
  console.log(args);
  console.log(args1);
}
foo(1, 2, 4564, "m", 65);


Array.of()

用于将一组值,转换为数组,弥补数组构造函数Array()的不足。因为参数个数的不同,会导致Array()的行为有差异。

let a= Array.of(3,11,8);
console.log(a);//[3.11.8]


find()

找出第一个符合条件的数组成员。

它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined。

let arrFind = [1, 22, 354, 480, 99];
let resFind = arrFind.find(
  (val, index, arrFind) => {
    return val > 100;
  });
console.log(resFind); //354


findIndex()

找出第一个符合条件的数组成员的位置

它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回-1。

let arrFindIndex = [1, 22, 354, 480, 99];
let resFindIndex = arrFindIndex.findIndex(
  (val, index, arrFindIndex) => {
    return val > 100;
  });
console.log(resFindIndex); //2


fill()

fill方法使用给定值,填充一个数组。

fill(填的数,开始位置,结束位置)

console.log(['a', 'b', 'c'].fill(7, 1, 2)); //[ 'a', 7, 'c' ]


includes()

返回一个布尔值,表示某个数组是否包含给定的值

a = ['a', 'b', 'c'];
console.log(a.includes('b')); //true


七丶字符串扩展

include

从一个字符串中找查自动字符串

let str = "myHello world!";
console.log(str.includes('world')); //true
console.log(str.includes('yes'));//false
console.log(str.includes('world', 9));//false


startsWith

返回布尔值,表示参数字符串是否在原字符串的头部。

let str='git://www.baidu.com/2123123';

    if(str.startsWith('http://')){
      alert('普通网址');
    }else if(str.startsWith('https://')){
      alert('加密网址');
    }else if(str.startsWith('git://')){
      alert('git地址');
    }else if(str.startsWith('svn://')){
      alert('svn地址');
    }else{
      alert('其他');
    }


endsWith

返回布尔值,表示参数字符串是否在原字符串的尾部。

    let str='1.png';

    if(str.endsWith('.txt')){
      alert('文本文件');
    }else if(str.endsWith('.jpg')){
      alert('JPG图片');
    }else{
      alert('其他');
    }


repeat

返回一个新字符串,表示将原字符串重复n次

console.log('x'.repeat(3));
//小数会取整数
console.log('x'.repeat(2.5));
//NaM 是 0
console.log('x'.repeat(NaN));
//字符串会转为数字
console.log('x'.repeat('5'));


padStart padEnd

用于头部 尾部补全

console.log('x'.padStart(5, 'ab'));//ababx
console.log('x'.padStart(4, 'ab'));//abax

console.log('x'.padEnd(5, 'ab'));//xabab
console.log('x'.padEnd(4, 'ab'));//xabao

//如果省略第二个参数,默认使用空格补全长度。
console.log('x'.padStart(4));//   x
console.log('x'.padEnd(4));//x


2.字符串模板

模板字符串(template
string)是增强版的字符串,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。

  • 直接把东西塞到字符串里面 ${东西}
  • 可以折行
let title='标题';
let content='内容';
let str='<div>
  <h1>'+title+'</h1>
  <p>'+content+'</p>
</div>';

let str2=`<div>
  <h1>${title}</h1>
  <p>${content}</p>
</div>`;


八丶ES6的面向对象

1.类,继承

//原来的
function User(name, pass){
this.name=name;
this.pass=pass;
}
//外挂方法
User.prototype.showName=function (){
alert(this.name);
};
User.prototype.showPass=function (){
alert(this.pass);
};
//继承
function VipUser(name, pass, level){
      User.call(this, name, pass);//继承属性
      this.level=level;
    }

    VipUser.prototype=new User();
    VipUser.prototype.constructor=VipUser;
    VipUser.prototype.showLevel=function (){
      alert(this.level);
    };

    var v1=new VipUser('blue', '123456', 3);

    v1.showName();
    v1.showPass();
    v1.showLevel();


//现在的
class User{
constructor(name, pass){
this.name=name;
this.pass=pass;
}

showName(){
alert(this.name);
}
showPass(){
alert(this.pass);
}
}
//继承
class VipUser extends User{
constructor(name, pass, level){
super(name, pass);
this.level=level;
}

showLevel(){
alert(this.level);
}
}

var v1=new VipUser('blue', '123456', 3);

v1.showName();
v1.showPass();
v1.showLevel();


1.class关键字、构造器和类分开了
2.class里面直接加方法

继承:

super=超类==父类

2.应用--react

React:
1.组件化——class
2.JSX=babel==browser.js

基础的东西

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <script src="react.js" charset="utf-8"></script>
    <script src="react-dom.js" charset="utf-8"></script>
    <script src="browser.js" charset="utf-8"></script>
    <script type="text/babel">
    window.onload=function (){
      let oDiv=document.getElementById('div1');

      ReactDOM.render(
        <span>123</span>,
        oDiv
      );
    };
    </script>
  </head>
  <body>
    <div >

    </div>
  </body>
</html>



组件

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <script src="react.js" charset="utf-8"></script>
    <script src="react-dom.js" charset="utf-8"></script>
    <script src="browser.js" charset="utf-8"></script>
    <script type="text/babel">
    class Item extends React.Component{
      constructor(...args){
        super(...args);
      }

      render(){
        return <li>{this.props.str}</li>;
      }
    }

    class List extends React.Component{
      constructor(...args){
        super(...args);
      }

      render(){
        return <ul>
          {this.props.arr.map(a=><Item str={a}></Item>)}
        </ul>;
      }
    }

    window.onload=function (){
      let oDiv=document.getElementById('div1');

      ReactDOM.render(
        <List arr={['abc', 'erw', 'sdfasdf', 'dfasdfsdfds']}></List>,
        oDiv
      );
    };
    </script>
  </head>
  <body>
    <div >

    </div>
  </body>
</html>



九丶json

1.标准写法

{"key": "aaa", "key2": 12} 


2.JSON对象

stringify 把json转换成字符串

    let json={a: 12, b: 5, c: 'aaa'};

    console.log(JSON.stringify(json));


parse 字符串转换json

    let str='{"a":12,"b":5,"c":"aaa"}';
    let json=JSON.parse(str);

    console.log(json);


十丶异步处理

异步——多个操作可以一起进行,互不干扰 √

$.ajax({
  url: 'data/1.json',
  dataType: 'json',
  success(data1){
    $.ajax({
      url: 'data/2.json',
      dataType: 'json',
      success(data2){
        $.ajax({
          url: 'data/3.json',
          dataType: 'json',
          success(data3){
            console.log(data1, data2, data3);
          }
        });
      }
    });
  }
});


同步——操作一个个进行

let data1=$.ajax('data/1.json');
let data2=$.ajax('data/2.json');
let data3=$.ajax('data/3.json');


Promise

  Promise.all([
      $.ajax({url: 'data/1.json', dataType: 'json'}),
      $.ajax({url: 'data/2.json', dataType: 'json'}),
      $.ajax({url: 'data/3.json', dataType: 'json'}),
    ]).then(([data1, data2, data3])=>{
      console.log(data1, data2, data3);
    }, (res)=>{
      alert('错了');
    });


async/await

 async function show(){
      let data1=await $.ajax({url: 'data/1.json', dataType: 'json'});
      if(data1.a<10){
        let data2=await $.ajax({url: 'data/2.json', dataType: 'json'});
        alert('a');
      }else{
        let data3=await $.ajax({url: 'data/3.json', dataType: 'json'});
        alert('b');
      }
    }


十一丶闭包

1.底层:栈
2.高层:函数当作对象处理

十二丶模块化

webpack

安装 npm i webpack -g

新建配置文件

webpack.config.js

const path=require('path');

module.exports={
  mode: 'production',
  entry: './index.js',
  output: {
    path: path.resolve(__dirname, 'build'),
    filename: 'bundle.js'
  }
};



1.entry——入口地址
2.output——输出
path:绝对路径
filename:文件名
3.mode——模式
4.所有当前路径前面加./

export

  export let a=xx;
  export const a=xx;

  export function xxx(){

  };

  export class xxx{

  }

  export {xxx, xxx, xxx, ...};

  export default xx;


导入模块

import * as mod from "./xxx";
import {a, b, c, ...} from "./xxx";


  //从另一个模块导出
  export * from './m2';
  export {x,x,x,x} from './m2';
  export {default} from './m2';


import

  import * as mod from "./xxx";
  import {a, b, c, ...} from "./xxx";

  //引入默认成员
  import xxx from './mod';

  //模块的代码引入进来,不引入内部成员
  import "./1.jpg";
  import "./1.css";

  //异步引入
  let promise=import("./mod1");