变量
ES6中增加了let和const用来声明变量
- var声明的变量可以重复声明、无法限制修改、没有if/for等块级作用域,只有函数作用域
- let声明的变量不能重复声明,变量可以修改,块级作用域
- const声明的常量不能重复声明,常量不允许修改,块级作用域
函数
箭头函数
ES6中增加了箭头函数,类似于lambda表达式 箭头函数里面的this指向上下文
- 如果只有一个参数,()可以省略
- 如果只有一个返回值,{}可以省略
箭头函数示例:
// 原来的写法
window.onload = function () {
alert('abc');
};
// 箭头函数写法
window.onload = ()=>{
alert('abc');
};
// 原来的带参数函数写法
let show = function(a,b){
alert(a + b);
};
// 箭头函数的带参数写法
let show = (a,b)=>{
alert(a,b);
};
// 例如数组排序
// 原来写法
let arr = [12,5,6,4,22,8,10];
arr.sort(funtion (n1, n2){
return n1 - n2;
});
// 箭头函数写法
let arr = [12,5,6,4,22,8,10];
arr.sort((n1, n2)=>{
return n1 - n2;
});
// 只有一个参数时小括号可以省略,只有一个return时大括号可以省略
let show = funtion(a) {
return a*2;
};
let show = a=>a*2;
函数的参数
参数的扩展/数组展开; 默认参数
参数扩展
收集剩余的参数```javascript function show(a, b, …args) { // ….除了a,b之外,函数的其余参数全部存放在args数组中
// 存放剩余参数的变量Rest Parameter必须为最后一个参数,后面不能再有其他参数
} ```
展开数组```javascript let arr = [1,2,3]; function show(a, b, c) { // ….. } show(…arr); // 将arr数组展开,对应到show的参数,等价于show(1,2,3)
// 将arr1、arr2数组中的值存入arr3数组中 // 数组展开后的效果,和直接把数组内容写在这里一样 let arr1 = [1,2,3]; let arr2 = [4,5,6]; let arr3 = […arr1, …arr2];
<a name="2171d1b0"></a>
#### 默认参数
```javascript
function show(a, b=5, c=12){
console.log(a, b, c);
}
show(99);
解构赋值
- 左右两边结构必须一样
- 右边必须是个东西
- 声明和赋值不能分开(必须在一句话里完成)
// 原来的写法
let arr = [1,2,3];
let a = arr[0];
let b = arr[1];
let c = arr[2];
// 解构赋值写法
let [a, b, c] = arr;
// JSON解构赋值,找json中对应名称的值,左右两边的结构同时为json
let testJson = {a:1,b:2,c:3,d:4};
let {a, c} = testJson;
// 解构赋值时,左右两边必须结构一致
let [{a,b}, [n1, n2, n3], d, e] = [{a:1, b:2, c:3}, [4, 5, 6], 7, 'aaa'];
// 可以解析成任意粒度
let [testJson, [n1, n2, n3], d, e] = [{a:1, b:2, c:3}, [4, 5, 6], 7, 'aaa'];
// 可以在数组、json中使用...语法创建剩余变量数组
let [first, ...rest] = [1, 2, 3, 4];
// 仅赋值某几个变量
let [ , second, , fourth] = [1, 2, 3, 4];
数组
map:一个对一个的进行映射 reduce:汇总,进来一堆,返回一个。 filter:过滤,通过返回值true或false决定是否保留 forEach:循环迭代
// map示例
// 返回数组对应每个分值是否及格
let arr = [55,20,66,42,80,11,100];
let result = arr.map(item => item>=60?'及格':'不及格');
// reduce示例
// 求最大值
let arr = [12,5,6,49,23,42,55,14,35];
// 循环 两两运算,tmp为中间结果,item为数组每项值,index为计算次数
var result = arr.reduce(function (tmp, item, index) {
return tmp > item ? tmp:item;
});
// 求平均值
let arr = [12,5,6,49,23,42,55,14,35];
// 循环 两两运算,tmp为中间结果,item为数组每项值,index为计算次数
var result = arr.reduce(function (tmp, item, index) {
if(index == arr.length-1) {
return (tmp+item)/arr.length;
}else{
return tmp+item;
}
});
// filter示例
// 返回只含有被3整除的数字的数组
let arr = [12,5,6,49,23,42,55,14,35];
var result = arr.filter(item => item%3==0);
// forEeach示例
// forEach可以有一个参数item,也可以有两个参数index,item
let arr = [12,5,6,49,23,42,55,14,35];
arr.forEach(item => alert(item));
字符串
- 多了两个新方法
- startsWith
- endsWith
- 字符串模板
- 直接把东西塞到字符串里面:$(东西)
- 字符串中可以换行
// 以前的写法
let title = '标题';
let content = '内容';
let str = '<div>\
<h1>' + title + '</h1>\
<p>' + content + '</p>\
</div>';
// 字符串模板写法
let title = '标题';
let content = '内容';
let str = `<div>
<h1>${title}</h1>
<p>${content}</p>
</div>`;
面向对象
- 多了class关键字,使得构造器和类分开
- class里面直接加方法
原来的js类写法:
// User既是类,又是构造方法,两者未分开
function User(name, pass) {
this.name = name;
this.pass = pass;
// 在构造方法中为类添加函数
this.show=function (){
alert(this.name + ' is ' + this.pass);
}
}
// 使用原型链为类添加属性
User.prototype.sex = '男';
// 使用原型链为类增加函数
User.prototype.showName = function (){
alert(this.name);
};
User.prototype.showPass = function () {
alert(this.pass);
};
// 静态属性
User.level = 1;
// 静态方法
User.getInfo = function (){
alert('静态方法');
}
// 调用静态方法
User.getInfo();
// 实例化对象调用
var u1 = new User('zhangsan', '123456');
u1.showName();
u1.showPass();
// 继承 (构造函数对象冒充 + 原型链 组合继承)
function VipUser(name, pass, level) {
// 单独用对象冒充可以继承构造函数里面的属性和方法,但是没法继承原型链上的属性和方法
User.call(this, name, pass); // 使用call获取父类的构造方法(对象冒充实现继承)
this.level = level;
}
// 原型链实现继承(单独用原型链继承,可以继承构造函数里面的属性和方法,也可以继承原型链上的属性和方法)
// 但是单独用原型链实现的继承,在实例化子类的时候,没法给对象传参
VipUser.prototype = new User(); // 将User的方法继承到VipUser原型上
VipUser.prototype.constructor = VipUser; // 再将VipUser的构造方法还原成VipUser本身的构造方法
VipUser.prototype.showLevel = function () {
alert(this.level);
}
var v1 = new VipUser('testVip', '123456', 12);
v1.showName();
v1.showPass();
v1.showLevel();
ES6的类写法:
class User{
constructor(name, pass) {
this.name = name;
this.pass = pass;
}
showName() {
alert(this.name);
}
showPass() {
alert(this.pass);
}
}
var u1 = new User('zhangsan', '123456');
u1.showName();
u1.showPass();
// 继承
class VipUser extends User{
constructor(name, pass, level) {
super(name, pass);
this.level = level;
}
showLevel(){
alert(this.level);
}
}
面向对象在React框架中的应用
react框架: 1.组件化—-class; 2.JSX(JSX == babel == browser.js)
JSON
json标准写法
- 只能用双引号
- 所有的名字都必须用引号包起来
- JSON对象
- JSON.stringify
- JSON.parse
- 简写
- 名字和值(key和value)一样的,留一个就行
- 方法,冒号和function关键字一起省略
```javascript
// 原来的写法
var a = 1;
var b = 2;
var testJson = {“a”: a,
"b": b,
"c": 120,
show : function (){
// .....
}
};
// 简写
// key的双引号可以省略
let testJson = {a:a , b:b, c: 120}
// 名称和值变量相同的,只需留一个
let testJson = {a, b, c:120}
// 函数的冒号和function关键字可以省略
let testJson = {
show(){
//…
}
}
<a name="Promise"></a>
## Promise
> 异步:操作之间没有关系,同时进行多个操作。
> 同步:同时只能做一件事。
> 异步:代码更复杂。
> 同步:代码简单
原始的同步异步代码,例如:
```javascript
// 异步
ajax("/banners", function(banner_data){
ajax("/hotItems", function(hotItems_data){
ajax("/slides", function(slides_data){
//....
},function(){
alert('读取失败');
});
},function(){
alert('读取失败');
});
},function(){
alert('读取失败');
});
// 同步
let banner_data = ajax_async('/banners');
let hotItem_data = ajax_async('/hotItems');
let slide_data = ajax_async('/slides');
Promise : 消除异步操作
用同步一样的方式,来书写异步代码
Promise中存放单一的ajax示例:
// new一个Promise对象
let p = new Promise(function (resolve, reject){
// 异步代码
// resolve -- 成功了
// reject -- 失败了
$.ajax({
url: "arr.txt",
dataType: 'json',
success(arr){
resolve(arr);
},
error(err){
reject(err);
}
});
});
// 当Promise执行有结果时,调用then
// then的参数中,第一个函数为成功时执行的函数,即resolve()
// then的参数中,第二个函数为失败时执行的函数,即reject()
p.then(function(arr) {
alert('成功' + arr);
}, function(err) {
alert('失败' + err);
});
Promise中存放多个ajax示例:
// 第一个ajax
let p1 = new Promise(function(resolve, reject){
$.ajax({
url:'arr.txt',
dataType:'json',
success(arr){
resolve(arr);
},
error(err){
reject(err);
}
});
});
// 第2个ajax
let p2 = new Promise(function(resolve, reject){
$.ajax({
url:'testJson.txt',
dataType:'json',
success(testJson){
resolve(testJson);
},
error(err){
reject(err);
}
});
});
// 当所有的Promise都成功时,执行then
Promise.all([p1,p2]).then(function(arr){
// 成功后的arr为一个数组,数组中每项值为对应前面的Promise对象的结果
let [result1, result2] = arr;
alert("全都成功了");
alert("p1的结果为" + result1);
alert("p2的结果为" + result2)
}, function(err){
alert("至少一个失败了");
});
对上面示例进行封装:
function createPromise(url){
return new Promise(function(resolve, reject){
$.ajax({
url,
dataType:'json',
success(testJson){
resolve(testJson);
},
error(err){
reject(err);
}
});
}
Promise.all([
createPromise('arr.txt');
createPromise('testJson.txt');
]).then(function(arr){
let [result1, result2] = arr;
alert("全都成功了");
alert("p1的结果为" + result1);
alert("p2的结果为" + result2)
}, function(err){
alert("至少一个失败了");
});
Jquery本身带有的Promise
// jQuery的ajax返回值就是一个Promise对象
let p = $.ajax(url:'arr.txt', dataType:json);
// 所以,Jquery的ajax可以直接写在Promise的all数组中
Promise.all([
$.ajax(url:'arr.txt', dataType:json);
$.ajax(url:'testJson.txt', dataType:json);
]).then(function(arr){
let [result1, result2] = arr;
alert("全都成功了");
alert("p1的结果为" + result1);
alert("p2的结果为" + result2)
}, function(err){
alert("至少一个失败了");
});
Promise的其他方法:
// Promise.race,哪个执行的最快,就返回哪个结果,不管结果本身是成功状态还是失败状态
Promise.race([
$.ajax(url:'arr.txt', dataType:json);
$.ajax(url:'testJson.txt', dataType:json);
]).then(function(arr){
alert("成功了" + result1);
}, function(err){
alert("失败了");
});
generator
generator是一种特殊的函数。 普通函数—-执行时一路执行到底; generator函数——执行的过程中间可以暂停
// generator函数写法:function和函数名之间加星号
// 可以写为 function* show(){...}; function *show(){...}; function * show(){...};
// 不能写为 function*show(){...}
// 不能写为箭头函数 *show()=>{....}
function *show(){
alert(1);
alert(2);
yield; // 使用yield关键字,放弃运行状态,运行到这里就停止
alert(3);
alert(4);
}
// 直接调用show()不会执行,返回一个generator对象
let genObj1 = show();
// next()执行到yield就停止
genObj1.next();
// yield暂停期间,可以执行其他代码
alert(5);
// 再次调用next()继续执行
genObj1.next();
yield可以传参
// 定义函数时,可以选择有参数函数
function *show(num1, num2) {
alert(`${num1},${num2}`);
alert(1);
// yield和上面的代码一起执行,然后暂停,下次next时传入的参数222返回给a
let a = yield;
alert(a);
alert(2);
}
let genObj = show(1, 2); // 给函数传入参数num1,num2
genObj.next(111); // 此处传入的111没有任何作用
alert(5);
genObj.next(222); // 此处传入的222将作为yield值,传递给let a
yield可以return
function *show(){
alert(1);
yield 12;
alert(2);
return 55;
}
let genObj = show();
let res1 = genObj.next(); // 可以获取到当前yield的返回值
console.log(res1); // JSON类型:{value:12, done:false}
let res2 = genObj.next(); // 最后一次的值是通过return获取
console.log(res2); // JSON类型: {value:55, done:true}
yield传参和返回,伪代码示例:
function *炒菜 (菜市场买回来的原材料){
// ... 洗菜
yield '洗好的菜';
// ...切菜
let 配料 = yield '切好的菜';
// ...炒菜
return '炒熟的菜';
}
let genObj = 炒菜();
let res1 = genObj.next(); // 获取到'洗好的菜'。炒菜过程未完成,done=false
// ...调制配料
let res2 = genObj.next(); // 获取到'切好的菜'
let res3 = genObj.next('配料'); // 将'配料'传进炒菜过程,最终获取到'炒熟的菜',炒菜过程完成,done=true
可以使用generator函数编写异步操作,类似Promise。
Promise适合场景:Promise中的所有异步ajax都需要读,一次读一堆;
generator适合场景:generator中间需要很多逻辑判断,后续操作需要根据前面的结果有条件操作;
ES7&8预览功能
数组
多了includes方法:数组是否包含某个东西
javascript let arr = [12,5,8]; alert(arr.includes(12));
keys/values/entries> keys:所有的key;
values:所有的value; entries:所有的实体(即键值对)
for…of循环:循环iterator迭代器
for—-in循环:循环数组、JSON```javascript
let arr = [12,5,8,32];
// for…in循环
for(let i in arr){
alert(i); // alert的i为arr的key:0,1,2,3,
}
// for…of循环
for(let i of arr) {
alert(i); // alert的i为arr的value:12,5,8,32
}
// json遍历
let testJson = {a: 12, b: 5, c:8};
for(let i in testJson) {
alert(i); // alert的i为json的key:a,b,c
}
// JSON不是可迭代对象,不能使用for…of循环
for(let i of testJson) {
alert(i);
}
```javascript
let arr = [12, 5, 8, 22];
// 使用for..of遍历arr的key
for(let i of arr.keys()) {
alert(i);
}
// 使用for...of遍历arr的value
for(let i of arr.values()) {
alert(i);
}
// 使用for...of遍历arr的键值对
for(let [key,value] of arr.entries()) {
alert(`${key}=${value}`);
}
幂
使用**
来进行幂次运算
alert('2的3次方=' (2**3));
字符串
ES7的字符串新增加了两个方法:
- padStart:左边补齐多少位
- padEnd:右边补齐多少位
alert('abc'.padStart(5)); // 左边补2个空格凑足5位长度
alert('123'.padStart(5,'0')); // 左边补2个0凑足5位长度
alert('123'.padStart(5,'0')); // 右边补2个0凑足5位长度
语法容忍度
某些“错误”的语法正常执行
数组语法容忍
javascript // ES6功能,数组最后多了一个逗号,依然可以正常执行 let arr = [12, 5, 8, 6, ];
函数参数语法容忍
javascript // ES7功能,函数参数最后多了一个逗号,依然可以正常执行 function show(num1, num2, ){ //... }
async和awaite
用来替代generator yield。 原来的generator会被封装一个runner进行执行,async不再依赖外部的runner。 async 可以写成箭头函数。
// 原来的generator的runner写法
runner(function *readData(){
let data1 = yield $.ajax({url: 'data/1.txt', dataType: 'json'});
let data2 = yield $.ajax({url: 'data/2.txt', dataType: 'json'});
let data2 = yield $.ajax({url: 'data/3.txt', dataType: 'json'});
console.log(data1,data2,data3);
});
// async写法
async function readData(){
let data1 = await $.ajax({url: 'data/1.txt', dataType: 'json'});
let data2 = await $.ajax({url: 'data/1.txt', dataType: 'json'});
let data3 = await $.ajax({url: 'data/1.txt', dataType: 'json'});
console.log(data1, data2, data3);
}
readData();
//async的箭头函数写法
let readData = async ()=>{
//...
}