ES6的一些新特性

let变量声明及声明特性

声明变量:

let a;
let b,c,d;
let e = 100;
let f = 521, g = 'hello', h = [];

特性:

  1. 变量不能重复声明(防止变量污染)
//ES6
let star = 'a';
let star = 'b';     //报错

//ES5
var str = 'abc';
var str = 'def';    //不报错
  1. 块级作用域(ES5:全局、函数、eval)
{
    let a = 12;
}
console.log(a);     //报错

//if else while for块级作用域中同样有效
  1. 不存在变量提升
//ES6
console.log(song);      //报错
let song = 'Maria';

//ES5
console.log(song);      //undefined
var song = 'Maria';
  1. 不影响作用域链
{
    let school = 'XUPT';
    function fn(){
        console.log(school);
    }
    fn();   //XUPT
}

实例:

点击一个div使其背景颜色变为粉色

let items = document.getElementsByClassName('item');

//使用var
//若使用itmes[i].style.background,则点击任意一个div都不会变色,i在全局作用域中,循环后会增加变为3
for(var i = 0; i < items.length; i++){
    items[i].onclick = function(){
        this.style.background = 'pink';
    }
}
console.log(window.i);  //3

//使用let
for(let i = 0; i < items.length; i++){
    items[i].onclick = function(){
        itmes[i].style.background = 'pink';
    }
}

const声明常量以及特点

声明常量:

const SCHOOL = 'XUPT';

特点:

  1. 一定要赋初始值
const A;    //报错
  1. 一般常量使用大写(潜规则)
  2. 常量的值不可修改,不可重复声明
const SCHOOL = 'XUPT';
SCHOOL = 'ABC';     //报错
const SCHOOL = 'SSS';   //报错
  1. 块级作用域
{
    const PLAYER = 'UZI';
}
console.log(PLAYER);    //报错
  1. 对于数组对象的元素修改,不算做对常量的修改,不会报错
const TEAM = ['UZI','MLXG','Ming','letme'];
TEAM.push('Meki0');     //虽然数组内容变化,但常量保存的地址未变,故不会报错
TEAM = 100;     //报错

本质:const实际上保证的并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。

  • 对于简单数据类型(数值、字符串、布尔值)而言,值就保存在变量指向的内存地址中,因此等同于常量。
  • 对于符合类型数据(主要是对象和数值)而言,变量指向的内存地址保存的只是一个指针,const只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,完全不能控制。

顶层对象的属性:

  • var,function命令声明的全局变量依旧是顶层对象的属性。
  • let,const,class命令声明的全局变量不属于顶层对象的属性。
var a = 1;
console.log(window.a);  //1

let b = 1;
console.log(window.b);  //undefined

变量的解构赋值

ES6允许按照一定模式从数组和对象中提取值,对变量进行赋值,这被称作解构赋值。

  1. 数组的解构赋值
const F4 = ['老王','老李','老张','老邓'];
let [wang,li,zhang,deng] = F4;
console.log(wang);      //老王
console.log(li);        //老李
console.log(zhang);     //老张
console.log(deng);      //老邓
  1. 对象的解构赋值
const wang = {
    name: '老王',
    age: 30,
    job: function(){
        concole.log('programmer');
    }
}
let {name,age,job} = wang;
console.log(name);  //老王
console.log(age);   //30
console.log(job);   //fn()
job();      //programmer

模板字符串

ES6引入新的声明字符串方式 `` 反引号。(ES5:''""


面向对象

原来写法
- 类和构造函数一样
- 属性和方法分开写的

// 老版本
function User(name, pass) {
    this.name = name;
    this.pass = pass;
}
User.prototype.showName = function () {
    console.log(this.name);
}
User.prototype.showPass = function () {
    console.log(this.pass);
}
var u1 = new User('able', '1233');
u1.showName();  //able
u1.showPass();  //1233


// 老版本继承
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 () {
    console.log(this.level);
}
var v1 = new VipUser('blue', '1234', 3);
v1.showName();  //blue
v1.showPass();  //1234
v1.showLevel(); //3

版面向对象
- 有了 class 关键字、构造器
- class 里面直接加方法
- 继承,super 超类==父类

//新版本
class User {
    constructor(name, pass) {
        this.name = name;
        this.pass = pass;
    }
    showName() {
        console.log(this.name);
    }
    showPass() {
        console.log(this.pass);
    }
}
var u1 = new User('able2', '111');
u1.showName();  //able2
u1.showPass();  //111


// 新版本继承
class VipUser extends User {
    constructor(name, pass, level) {
        super(name, pass);
        this.level = level;
    }
    showLevel(){
        console.log(this.level);
    }
}
v1 = new VipUser('blue', '123', 3);
v1.showLevel(); //3

JSON

1.JSON 格式
- JavaScript Object Notation 的缩写,是一种用于数据交换的文本格式
- JSON 是 JS对象 的严格子集
- JSON 的标准写法:

  • 只能用双引号
  • 所有的key都必须用双引号包起来

2.JSON 对象
- JSON 对象是 JavaScript 的原生对象,用来处理 JSON 格式数据,有两个静态方法
- JSON.parse(string) :接受一个 JSON 字符串并将其转换成一个 JavaScript 对象
- JSON.stringify(obj) :接受一个 JavaScript 对象并将其转换为一个 JSON 字符串

//JSON.stringify(obj)将对象转化为字符串
var json = {a: 12, b: 5};
var str = 'hi,' + JSON.stringify(json);
var url = 'http://www.xx.com/' + encodeURIComponent(JSON.stringify(json));
console.log(str);   //hi,{"a":12,"b":5}
console.log(url);   //http://www.xx.com/%7B%22a%22%3A12%2C%22b%22%3A5%7D


//JSON.parse(string)将字符串转化为对象
var str = '{"a": 12, "b": 4, "c": "abc"}';
var json = JSON.parse(str);
console.log(json);  //{ a: 12, b: 4, c: 'abc' }

3.对象 简写
- 名字和值(key-value) 一样时可以简写,留一个就行
- 里面的函数可以简写, 去掉:function

var a = 12, b = 5;
console.log({a:a, b:b});    //{ a: 12, b: 5 }
console.log({a, b});    //{ a: 12, b: 5 }
console.log({a, b, c:"c"});     //{ a: 12, b: 5, c: 'c' }

console.log({ a, b, show(){ console.log('a') }});   
//{ a: 12, b: 5, show: [Function: show] }

Promise

1.异步和同步

  • 异步:操作之间没有关系,同时执行多个操作, 代码复杂
  • 同步:同时只能做一件事,代码简单

2.Promise 对象

  • 用同步的方式来书写异步代码
  • Promise 让异步操作写起来,像在写同步操作的流程,不必一层层地嵌套回调函数
  • 改善了可读性,对于多层嵌套的回调函数很方便
  • 充当异步操作与回调函数之间的中介,使得异步操作具备同步操作的接口

3.Promise 也是一个构造函数

  • 接受一个回调函数f1作为参数,f1里面是异步操作的代码
  • 返回的p1就是一个 Promise 实例
  • 所有异步任务都返回一个 Promise 实例
  • Promise 实例有一个then方法,用来指定下一步的回调函数
function f1(resolve, reject) {
  // 异步代码...
}
var p1 = new Promise(f1);
p1.then(f2); // f1的异步操作执行完成,就会执行f2

4.Promise 使得异步流程可以写成同步流程

// 传统写法
step1(function (value1) {
  step2(value1, function(value2) {
    step3(value2, function(value3) {
      step4(value3, function(value4) {
        // ...
      });
    });
  });
});


// Promise 的写法
(new Promise(step1))
  .then(step2)
  .then(step3)
  .then(step4);

5.Promise.all(promiseArray)方法

  • 将多个Promise对象实例包装,生成并返回一个新的Promise实例
  • promise数组中所有的promise实例都变为resolve的时候,该方法才会返回
  • 并将所有结果传递results数组中
  • promise数组中任何一个promise为reject的话,则整个Promise.all调用会立即终止,并返回一个reject的新的promise对象
var p1 = Promise.resolve(1),
    p2 = Promise.resolve(2),
    p3 = Promise.resolve(3);
Promise.all([p1, p2, p3]).then(function (results) {
    console.log(results);  // [1, 2, 3]
});

6.Promise.race([p1, p2, p3])

  • Promse.race就是赛跑的意思
  • 哪个结果获得的快,就返回那个结果
  • 不管结果本身是成功状态还是失败状态

generator-生成器函数

  • 普通函数,一路到底
  • generator函数,中间可以停,到哪停呢,用 yield 配合,交出执行权
  • yield 有 放弃、退让、退位的意思
  • 需要调用next()方法启动执行,需要遇到 yield 停, 踹一脚走一步
  • generator函数前面加一个 * 两边可以有空格,或靠近函数或function
  • 背后实际生成多个小函数,实现走走停停
function show() {
    console.log('a')
    console.log('b')
}
show() // 普通函数

function *show2() {
    console.log('1')
    yield
    console.log('2')
}
let genObj = show2()
genObj.next() // 1
genObj.next() // 2
genObj.next() // 最后了,没有结果

generator-yield

1.yield

  • 既可传参,又可以返回
  • 第一个next()传参无效,只用来启动

2.如果函数前漏掉 *

  • 就是普通函数
  • 如果有yield会报错, ReferenceError: yield is not defined
  • yield 只能在Generator函数内部使用
function * show() {
    console.log('1')
    var a = yield
    console.log('2')
    console.log(a)
}
// yield 传参
var gen = show()
gen.next() // 1
gen.next() // 2 和 undefined 因为没有传参,yield没有返回值
var gen = show()
gen.next(10) // 1 第一次执行到yield,但没有执行赋值
gen.next(20) // 2 和 20

function* show2() {
    console.log('1')
    yield 10
    console.log('2')
}
// yield 返回
var gen = show2()
var res1 = gen.next()
console.log(res1) // { value: 10, done: false }
var res2 = gen.next()
console.log(res2)
// { value: undefined, done: true } 最后的value需要return返回
generator-实例
  • Promise 适合一次读一组
  • generator 适合逻辑性的
// 带逻辑-generator
runner(function * () {
    let userData = yield $.ajax({url: 'getUserData'})

    if (userData.type == 'VIP') {
        let items = yield $.ajax({url: 'getVIPItems'})
    } else {
        let items = yield $.ajax({url: 'getItems'})
    }
})
// yield 实例,用同步方式写异步
server.use(function * () {
    let data = yield db.query(`select * from user_table`)
    this.body = data
})

你可能感兴趣的:(ES6的一些新特性)