ECMAScript与JavaScript的关系java
ECMA是European Computer Manufacturers Association的缩写,即欧洲计算机制造商协会。欧洲计算机制造商协会是制定信息传输与通信的国际化标准组织。
1996年11月,JavaScript的创造者Netscape公司,决定将JavaScript提交给ECMA,但愿这种语言可以成为国际标准。次年,ECMA发布262号标准文件(ECMA-262)的初版,规定了浏览器脚本语言的标准,并将这种语言称为ECMAScript,这个版本就是1.0版。
该标准从一开始就是针对JavaScript语言制定的,但之因此不叫JavaScript,有两个缘由。一是商标,Java是Sun公司的商标,根据受权协议,只有Netscape公司能够合法地使用JavaScript这个名字,且JavaScript自己也已经被Netscape公司注册为商标。二是想体现这门语言的制定者是ECMA,不是Netscape,这样有利于保证这门语言的开放性和中立性。
所以,ECMAScript和JavaScript的关系是,ECMA是JavaScript的标准,JavaScript是ECMA的一种实现。jquery
历史版本git
时间 | 版本 | 详情 |
---|---|---|
1996.11 | ES 1.0 | 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开始指向ES 7.0 |
ES6兼容性查看:http://kangax.github.io/compat-table/es6/es6
使用Babel解决ES6兼容性问题github
提早编译ajax
首先咱们建立一个html文件,在里面输入ES6的新语法,用低版本浏览器运行这个文件。编程
<script> let a = 1; console.log(a); </script>
这样咱们的低版本浏览器会报错:json
此次咱们引入在线的babel.min.js,咱们还要在script脚本中声明类型为”text/babel”,这样就能够在低版本浏览器中运行ES6的新语法了。
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.4.4/babel.min.js"></script> <script type="text/babel"> let a = 1; console.log(a); </script>
此次咱们成功获得了console.log的结果:
1.能够重复声明,在团队协做时很容易形成冲突
var a = 1; var a = 2;
2.没法限制修改,没有常量的概念
var a = 1; a = 2;
3.不支持块级做用域,属于函数级做用域
if ( true ) { var a = 1; } alert(a);
let a = 1; let a = 2; const a = 1; const a = 2;
2. 支持块级做用域,在做用域内定义的变量或常量只能在做用域内使用
if ( true ) { let c = 1; } console.log(c);
if ( true ) { const PI = 3.14; } console.log(PI);
var arr = [1, 2, 3]; var a = arr[0]; var b = arr[1]; var c = arr[2]; console.log(a, b, c);
let [a, b, c] = [1, 2, 3]; console.log(a, b, c);
function fn(a){ return a * 2; } console.log(fn(5)); //10
let fn = (a) => { return a * 2; } console.log(fn(5)); //10
let fn = a => a * 2; console.log(fn(5)); //10
let fn = (a, b, ...args) => { console.log(a); //1 console.log(b); //2 console.log(args); //[3, 4, 5] } fn(1, 2, 3, 4, 5);
let arr1 = [1, 2, 3]; let arr2 = [4, 5, 6]; let arr = [...arr1, ...arr2]; console.log(arr); //[1, 2, 3, 4, 5, 6]
let fn = (a, b=2, c=3) => { console.log(a, b, c); //1, 5, 3 } fn(1, 5);
ES6新增了4个数组方法:map、reduce、filter、forEach
检查分数是否及格
let arr = [59, 60, 99, 31, 85]; let result = arr.map(item => item >= 60 ? "及格" : "不及格"); console.log(result); //["不及格", "及格", "及格", "不及格", "及格"]
let arr = [10, 20, 30, 40]; let result = arr.reduce((tmp, item, index) => tmp + item); console.log(result); //100
let arr = [1, 2, 3, 4, 5]; let result = arr.reduce((tmp, item, index, arr) => { if ( index != arr.length-1 ) { //不是最后一次先求和 return tmp + item; } else { //最后一次求平均数 return (tmp + item)/arr.length; } }); console.log(result); //3
根据条件判断,去掉不想要的数据,返回想保留的数据
let arr = [5, 7, 10, 13, 15, 20, 25]; let result1 = arr.filter(item => { if ( item%5 == 0 ) { //判断可不能够被5整除 return true; //保留能够被5整除的数 } else { return false; //去掉不能被5整除的数 } }); //能够简写成下面这种方式,直接经过布尔值判断,为true的保留,为false的去掉 let result2 = arr.filter(item => item%5 == 0); //保留能够被5整除的数 //这样获得的结果是同样的 console.log(result1); //[5, 10, 15, 20, 25] console.log(result2); //[5, 10, 15, 20, 25]
遍历数组,第一个参数是数组的值,第二个参数是数组的下标
let arr = [2, 5, 6, 9, 7, 54]; arr.forEach((item, index) => { console.log(index + ":" + item); //0:2, 1:5, 2:6, 3:9, 4:7, 5:54 });
ES6新增了2个字符串方法:startsWith、endsWith
let str = "https://www.baidu.com/"; console.log(str.startsWith("https://")); //true
let str = "1.txt"; console.log(str.endsWith(".txt")); //true
var title = "标题"; var content = "内容"; var str = "<div>\ <h2>title:"+title+"</h2>\ <p>content:"+content+"</p>\ </div>";
let title = "标题"; let content = "内容"; let str = `<div> <h2>title:${title}</h2> <p>content:${content}</p> </div>`;
function My(name, age){ //构造函数假装成类来使用 this.name = name; this.age = age; } /*函数须要用prototype来追加,与主体分离,比较分散不便于维护*/ My.prototype.showName = function (){ alert(this.name); } My.prototype.showAge = function (){ alert(this.age); } var my = new My('Sain', 26); my.showName(); //Sain my.showAge(); //26
class My{ //使用class关键字定义一个类 constructor(name, age){ this.name = name; this.age = age; } showName(){ alert(this.name); } showAge(){ alert(this.age); } } var my = new My('Sain', 26); my.showName(); //Sain my.showAge(); //26
function addMyWeight(name, age, weight){ //若是想在刚才My这个类的基础上增长新的属性就要使用继承 My.call(this, name, age); //经过call来继承父级 this.weight = weight; } addMyWeight.prototype = new My(); addMyWeight.prototype.constructor = addMyWeight; addMyWeight.prototype.showWeight = function (){ alert(this.weight); } var my = new addMyWeight('Sain', 26, '80kg'); my.showName(); //Sain my.showAge(); //26 my.showWeight(); //80kg
class addMyWeight extends My{ //使用ES6的extend来继承My这个类 constructor(name, age, weight){ super(name, age); //等同于call继承父级 this.weight = weight //增长新属性 } showWeight(){ //增长新方法 alert(this.weight); } } var my = new addMyWeight('Sain', 26, '80kg'); my.showName(); //Sain my.showAge(); //26 my.showWeight(); //80kg
JSON.stringify()
方法将json数据转化成字符串let json = {"a":10, "b": 5}; let str = JSON.stringify(json); console.log(str); //{"a":10, "b": 5} console.log(typeof str); //"string"
JSON.parse()
方法将字符串转换成json,字符串必须严格遵照json格式要求,key和value要用双引号包起来,value若是是数字的状况下能够不使用双引号。let str = '{"a": 10, "b": "hello"}'; let json = JSON.parse(str); console.log(json); //Object {a: 10, b: "hello"} console.log(typeof json); //object
let a = 1; let b = 2; let json = {a: a, b: b, c: 3}; let json = {a, b, c: 3}; //简写
let json = { a: "hello", say: function(){ //能够省略:和function,简写成say() alert(this.a); } } json.say(); //hello
八、Promise
Promise——承诺
8.1 异步
操做之间没有关系
同时进行多个操做
回调写法代码复杂(回调地狱)
下面是异步操做代码,若是想要同时读取不一样模块的数据,就要写成回调方式。
ajax('/top', function (top_data){
//top读取成功
ajax('/left', function (left_data){
//left读取成功
ajax('/right', function (right_data){
//right读取成功
ajax('/bottom', function (bottom_data){
//bottom读取成功
},function (){
console.log('bottom读取失败');
})
},function (){
console.log('right读取失败');
})
},function (){
console.log('left读取失败');
})
},function (){
console.log('top读取失败');
})
8.2 同步
同时只能作一件事
代码排队执行
代码简单,方便维护
下面是同步代码,不一样模块分别调用,代码简洁:
let top_data = ajax_async('/top');
let left_data = ajax_async('/left');
let right_data = ajax_async('/right');
let bottom_data = ajax_async('/bottom');
8.3 Promise使用用法
Promise能够消除异步操做,用同步的方式来书写异步代码
let p = new Promise(resolve,reject){
$.ajax({
url: 'a.txt',
dataType: 'json',
success(data){
resolve(data); //resolve成功
},
error(err){
reject(err); //reject失败
}
})
}
p.then(function(data){
console.log('成功'+data);
}, function (err){
console.log('失败'+err);
});
8.4 Promise.all()的使用方法
咱们用Promise建立了两个异步操做,使用Promise.all()来同时执行这两个操做,若是所有成功了就成功了,若是其中有一个失败了就失败了,等同于&&的关系。
除了Promise.all(),还有Promise.race() 方法,这两个方法的使用方法同样,不同的是Promise.race()只执行成功的,忽略失败的,等同于||的关系。
let p1 = new Promise(resolve,reject){
$.ajax({
url: 'arr.txt',
dataType: 'json',
success(data){
resolve(data);
},
error(err){
reject(err);
}
})
}
let p2 = new Promise(resolve,reject){
$.ajax({
url: 'json.txt',
dataType: 'json',
success(data){
resolve(data);
},
error(err){
reject(err);
}
})
}
Promise.all([
p1, p2
]).then(
function (data){
let [res1,res2] = data; //解构赋值
console.log('所有成功了');
console.log(res1);
console.log(res2);
}, function (){
console.log('有一个失败了就是失败了');
}
)
8.5 封装Promise
function createPromise(url){
return new Promise(resolve,reject){
$.ajax({
url, //key和value同样,留一个就行
dataType: 'json',
success(data){
resolve(data);
},
error(err){
reject(err);
}
})
}
}
Promise.all([
createPromise('arr.txt');
createPromise('json.txt');
]).then(
function (data){
let [res1,res2] = data; //解构赋值
console.log('所有成功了');
console.log(res1);
console.log(res2);
}, function (){
console.log('有一个失败了就是失败了');
}
)
8.6 jquery的Promise使用
高版本jquery自带Promise支持
先在页面引入最新版本的jQuery<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
$.ajax({url: 'arr.txt, dataType: 'json'});
Promise.all([
$.ajax({url: 'arr.txt, dataType: 'json'});
$.ajax({url: 'json.txt, dataType: 'json'});
]).then(results => {
let [res1,res2] = results; //解构赋值
console.log('所有成功了');
console.log(res1);
console.log(res2);
}, err => {
console.log('有一个失败了就是失败了');
}
)
九、generator
generator生成器
普通函数:执行完才结束
generator函数:中间能暂停
9.1 generator函数的写法
在function和函数名中加上*,能够跟在function后面,也能够在function和函数名中间,也能够在函数名前面。
generator不能写成箭头函数方式。
function* show(){}
function * show(){}
function *show(){}
yield
```
function *show(){
console.log(1);
yield; //放弃执行
console.log(2);
}
let genObj = show(); //建立一个generator对象
genObj.next(); //1,调用next()执行一次
generator原理是生成了一堆小函数:
genObj.next(); //show_1(){console.log(1)};
genObj.next(); //show_2(){console.log(2)};
9.2 yield传参、返回
yield传参
function *show(){
let a = yield; //放弃执行
console.log(a); //5
}
let gen = show();
gen.next(10); //第一个next没法传参,第一个传参要写在generator函数参数里
gen.next(5);
根据上面代码咱们能够知道generator没法接收到第一个next方法的参数,咱们能够将第一个参数直接传入到generator函数参数里:
function *show(num){
console.log(num); //10
let a = yield; //放弃执行
console.log(a); //5
}
let gen = show(10); //第一个next()传参要写在generator函数参数里
gen.next();
gen.next(5);
generator原理是生成了一堆小函数:
genObj.next(); //show_1(){console.log(1)};
genObj.next(); //show_2(){console.log(2)};
yield返回
yield返回值有两个参数:
1. value就是generator函数执行到当前yield语句以后获得的值
2. done表示函数是否执行完成,true表明函数所有执行完成,flase表明函数暂停状态未执行完成
function *show(){
console.log(1);
let a = yield; //放弃执行
console.log(2);
return 3;
}
let gen = show();
let res1 = gen.next();
console.log(res1); //{value:1,done:false}
let res2 = gen.next();
console.log(res2); //{value:undefined,done:true}
console.log(res2); //{value:3,done:true} 最后的返回值要经过return返回
9.3 generator的用途
当Promise有逻辑执行的时候会比异步回调写法还麻烦,因此咱们在工做中遇到异步须要逻辑判断的时候可使用generator来写。
generator在有逻辑判断状况下写起来很简单
function *main(){
let data1 = yield $.ajax({url: '', dataType: 'json'});
if(data1.data == true) {
let data2 = yield $.ajax({url: '', dataType: 'json'});
} else {
let data3 = yield $.ajax({url: '', dataType: 'json'});
}
}
let gen = main();
————————————————