时间 | 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/javascript
支持IE10+、Chrome、FireFox、移动端、NodeJScss
不支持能够:html
1.在线转换java
<!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 而且执行node init -y
react
npm i @babel/core @babel/cli @babel/preset-env
webpack
添加脚本git
"scripts":{ "build":"babel src -d test" }
添加.babelrc——声明presetes6
{ "presets": ["@babel/preset-env"] }
**求幂github
Array.includes()
await/async
rest/spread
异步迭代
Promise.finally()
正则
1.能够重复声明
2.没法限制修改
3.没有块级做用域
if (true) { var a = 12; } alert(a)
不能重复声明,能够修改,支持块级做用域
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 a = 12; a = 123; alert(a);//TypeError: invalid assignment to const `a'
1.传统函数级
2.ES6块级
{} if(){ } for(){ } { }
使用对象字面量表示法
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 }
基本数据类型
console.log("具体值:", Object.is("hello", "hello")); //具体值: true
引用数据类型
console.log("具体值:", Object.is({}, {})); //具体值: false
用于对象的合并,将源对象(source)的全部可枚举属性,复制到目标对象(target)。
const a = { a: 1 }; const b = { b: 2 }; const c = { c: 3 }; let d = Object.assign(a, b, c) console.log(d);
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]); }
表示独一无二的值。
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
存储无重复值的有序列表
let set1 = new Set(); set.add(1); set.add('1'); set.delete('1'); set.has(1);//true console.log(set.size);//2 set.clear();
成员是对象
垃圾回收机制不用考虑存在于WeakSet中
不能迭代(没有 for of keys vaules forEach size
let ws = new WeakSet();
键值对的集合
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
遍历器(lterator)就是这样一种机制。它是一种接口,为各类不一样的数据结构提供统一的访问机制。任何数据结构只要部署terator接口,就能够完成遍历操做(即依次处理该数据结构的全部成员)。
参数默认值不是传值的,而是每次都从新计算默认值表达式的值。也就是说,参数默认值是惰性求值的。
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 属性将失真。
只是简写
function 名字(参数){ } (参数)=>{ }
let show=a=>a*2; alert(show(12));
用于获取函数的多余参数,这样就 不须要使用 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 属性,返回该函数的函数名。
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
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
//模块的制定输入
返回一个新数组;如没有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() 能够做为一个高阶函数,用于函数的 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);
过滤掉不知足条件的数据。
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);
let arr=[12,5,8,9]; arr.forEach((item,index)=>{ alert(index+': '+item); });
<button onclick="numbers.forEach(myFunction)">点我</button> <p id="demo"></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>
数组里所有元素知足条件,则返回true
var numbers = [5, 9, 11, 25, 11]; var res = numbers.every((item, index) => { return item % 2 == 1; }); alert(`every:${res}`); //every:ture
判断是否所有为奇数
数组里某一元素知足条件,则返回
var numbers = [5, 9, 2, 25, 11]; var res = numbers.some((item, index) => { return item % 2 == 1; }); alert(`some:${res}`); //some:ture
判断一个为偶数数
一个循环来迭代可迭代的对象。
用来替代 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
返回一个数组的迭代对象,该对象包含数组的键值对 (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
具备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()的不足。由于参数个数的不一样,会致使Array()的行为有差别。
let a= Array.of(3,11,8); console.log(a);//[3.11.8]
找出第一个符合条件的数组成员。
它的参数是一个回调函数,全部数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,而后返回该成员。若是没有符合条件的成员,则返回undefined。
let arrFind = [1, 22, 354, 480, 99]; let resFind = arrFind.find( (val, index, arrFind) => { return val > 100; }); console.log(resFind); //354
找出第一个符合条件的数组成员的位置
它的参数是一个回调函数,全部数组成员依次执行该回调函数,直到找出第一个返回值为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(填的数,开始位置,结束位置)
console.log(['a', 'b', 'c'].fill(7, 1, 2)); //[ 'a', 7, 'c' ]
返回一个布尔值,表示某个数组是否包含给定的值
a = ['a', 'b', 'c']; console.log(a.includes('b')); //true
从一个字符串中找查自动字符串
let str = "myHello world!"; console.log(str.includes('world')); //true console.log(str.includes('yes'));//false console.log(str.includes('world', 9));//false
返回布尔值,表示参数字符串是否在原字符串的头部。
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('其余'); }
返回一个新字符串,表示将原字符串重复n次
console.log('x'.repeat(3)); //小数会取整数 console.log('x'.repeat(2.5)); //NaM 是 0 console.log('x'.repeat(NaN)); //字符串会转为数字 console.log('x'.repeat('5'));
用于头部 尾部补全
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
模板字符串(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>`;
//原来的 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=超类==父类
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 id="div1"> </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 id="div1"> </div> </body> </html>
{"key": "aaa", "key2": 12}
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.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 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.高层:函数看成对象处理
安装 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 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 * as mod from "./xxx"; import {a, b, c, ...} from "./xxx"; //引入默认成员 import xxx from './mod'; //模块的代码引入进来,不引入内部成员 import "./1.jpg"; import "./1.css"; //异步引入 let promise=import("./mod1");