es6 笔记

01 简介
一、检测es6兼容性
http://kangax.github.io/es5-compat-table/es6
二、兼容包:traceur转码器

<script src="http://google.github.io/traceur-compiler/bin/traceur.js" type="text/script"></script>
<script>
traceur.options.experimental = true; // experimental /ɛk'spɛrɪ'mɛntəl/:实验的,试验性的
</script>
<script type="module"> // type得是module或者traceur,不是text/javascript
class Test = function() {}
</script>


三、es7
async函数:在promise和generator的基础上,提出的异步操作解决方案。

02 let基本用法
一、let不存在变量提升
二、let暂时性死区
只要块级作用域内存在let命令,它所声明的变量就”绑定“到这个区域,不再受外部的影响。
三、let不允许在相同作用域内,重复声明一个变量。

06 为什么需要块级作用域
一、为什么需要块级作用域
1、防止变量相互影响。
2、变量作用域内使用完后即销毁,减少内存占用。

var time = new Date();
function func() {
    console.log(time);
    if (false) {
        var time = "hello world"; // 声明的变量会提升,但是赋值没有提升
    }
}
func(); // 控制台输出”undefined“


08 const命令
一、const用来声明常量,声明的是常量。
常量:一旦声明,常量的值就不能改变。
对于引用类型,只要指向的内存地址没变,就是常量。
二、const对象

const person = {};
person.name = ‘zhangsan’; // 指向的内存地址没变
person = {}; // 报错:Uncaught TypeError: Assignment to constant variable.


 

const arr = [];
arr.push('hello');
arr.length = 0;
console.log(arr);
arr = ['hello world']; // 报错:Uncaught TypeError: Assignment to constant variable.


10 const对象冻结
一、使用const冻结对象

const person = Object.freeze({
    name: 'zhangsan',
    age: '30'
});
console.log(person.name); // 'zhangsan'
person.name = 'lisi';
console.log(person.name); // 'zhangsan'


二、彻底冻结对象(递归)

var constantize = obj => {
    Object.freeze(obj);
    Object.keys(obj).forEach((key, value) => {
        if (typeof obj[key] === 'object') {
            constantize(obj[key]);
        }
    })
}



11 跨模块常量
一、面向对象,模块至少是一个类。

12 全局对象属性
一、全局对象是最顶层的对象,在浏览器环境指的是window对象,在Node.js指的是global对象。在javsScript语言中,所有全局变量都是全局对象的属性(node的情况比较特殊,这条只对REPL捐精适用,模块环境必须显示声明成global的属性)。
二、es6规定,var命令和function命令声明的全局变量,属于全局对象的属性:let命令、const命令、class命令声明的全局变量,不属于全局对象的属性。

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



13 Destructuring 数组的解构赋值
一、结构destructuring
es6允许按照一点模式,从数组和对象中提取值,对变量进行赋值,这被称为解构。

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


 

let [foo, [[bar], base]] = [1, [[2], 3]];


二、不完全解构
等号左边的模式,只匹配一部分的等号右边的数组。

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



三、指定默认值
es6内部使用严格相等运算符(===)判断一个位置是否有值。所以,如果一个数组成员不严格等于undefined,默认值是不会生效的。

// 1
var [temp = 'string'] = [];
console.log(temp); // string
// 2:string为默认值,如果后面的数组没有值(为undefined,不为null),则temp为默认值string,如果有值,则为后面的值tempString。
var [temp = 'string'] = ['tempString'];
console.log(temp); // tempString


 

// 1
var a = 1;
a = undefined;
console.log(a); // undefined
// 2
var [x, y = "aaa"] = ["bbb", undefined];
console.log(x);  // bbb
console.log(y); // aaa
var [temp] = 1; // 不管是1,还是false、NaN、undefined、null都会报错(都是不可Iterable,不可迭代)。



四、let和const命令
只要某种数据结构具有iterator接口,都可以采用数组形式的解构赋值。
iterator/ɪtə’retɚ/:迭代器,迭代程序。

// 1
let [a, b, c] = new Set(['a', 'b', 'c']);
console.log(a); // a
// 2
 const [x, y, z, a, b, c] = new Set([3, 1, 2, 2, 3]); // new Set()处理后的数组:[3, 1, 2]
  console.log(x); // 3
  console.log(y); // 1
  console.log(z); // 2
  console.log(a); // undefined
  console.log(b); // undefined
  console.log(c); // undefined


 

function* fibs() { // function*表示生成器函数,生成器函数在执行时能暂停,后面又能从暂停处继续执行
    let a = 0;
    let b = 1;
    while (true) {
        console.log(`a:${a}`); // 0 1 1 2 3 5
          console.log(`b:${b}`); // 1 1 2 3 5 8
        yield a;
        [a, b] = [b, a+b];
    }
}
let [first, second, third, fourth, fifth, sixth] = fibs();
console.log(first); // 0
  console.log(second); // 1
  console.log(third); // 1
  console.log(fourth); // 2
  console.log(fifth); // 3
  console.log(sixth); // 5


1、yield是ES6的新关键字,使生成器函数执行暂停,yield关键字后面的表达式的值返回给生成器的调用者。它可以被认为是一个基于生成器的版本的return关键字。
2、yield关键字实际返回一个IteratorResult(迭代器)对象,它有两个属性,value和done,分别代表本次yeild表达式的返回值和是否完成(生成器后续是否还有yield语句)。
3、调用 next() 方法时,如果传入了参数,那么这个参数会作为上一条执行的 yield 语句的返回值。
4、当在生成器函数中显式 return 时,会导致生成器立即变为完成状态,即调用 next() 方法返回的对象的 done 为 true。如果 return 后面跟了一个值,那么这个值会作为当前调用 next() 方法返回的 value 值。
五、数组有length属性,可以对这个属性解构赋值 

 const {length: len}= ['hello','world'];
 console.log(len); // 2



17 对象的解构赋值
一、解构
对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

var {name, age} = {age: 28, name: 'Jack'};
console.log(age); // 28

 

// 1
var {userName: person_name, age: person_age} = {userName: 'Jack', age: 28}; // name的值赋给person_name
console.log(person_age); // 28
console.log(userName); // userName is not defined
// aSuncat:如果userName写成name,打印name并不会报错。因为name是全局对象window的属性,window.name是窗口的名字,窗口的名字主要用于为超链接和表单设置目标(targets)
// 2
let object = {first: 'Hello', last: 'World'};
let {first: firstName, last: lastName} = object;
console.log(firstName); // Hello



二、默认值生效的条件是,对象的属性值严格等于undefined

let {message: msg = "you are a person"} = {};
consolel.log(msg); // you are a person

 

let {x = 1} = {x: undefined};
console.log(x); // 1
let {y = 2} = {y: null};
console.log(y); // null


三、已声明变量的解构赋值

var x;
({x} = {x: 1}); // 如果没有(),会报错:Uncaught SyntaxError: Unexpected token =,javascript引擎会将{x}理解成一个代码块,这个代码块是没有声明的。
console.log(x); // 1


四、现有对象的方法
对象的解构赋值,可以很方便地将现有对象的方法,赋值到某个变量。

console.log(Math.sin(Math.PI/6)); // 0.49999...
浮动数运算机制
let {sin, cos, tan} = Math;
console.log(sin(Math.PI/6));



20 字符串的解构赋值
一、字符串被转换成了一个类似数组的对象。

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



二、属性解构赋值
类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。

const {length: len} = 'hello';
console.log(len);



21 函数参数的解构赋值
一、函数的参数也可以使用解构

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



二、函数的参数也能使用默认值

function fun({x = 0, y = 0} = {}) {
    return [x, y];
}
console.log(fun({x: 100, y: 200})); // [100, 200]
console.log(fun({x: 100})); // [100, 0]
console.log(fun({})); // [0, 0]
console.log(fun()); // [0, 0] 


 

function fun({x, y} = {x: 0, y:0}) {return [x, y]};
console.log(fun({x: 100})); // [100, undefined]
console.log(fun({})); // [undefined, undefined]
console.log(fun()); // [0, 0] // 没有在函数参数中解构赋值,只是对对象解构赋值,{x,y} = {x: 0, y: 0}会被当成是在函数中执行的语句



22 交换变量的值
一、解构赋值的用途
1、交换变量的值

// es5
var a = 100;
var b = 200;
var temp = a; // 多声明一个变量,就多占用一份内存空间
a = b;
b = temp;

// es6
let x = 100;
let y = 200;
[x, y] = [y, x]; // 交换x,y的值



2、从函数返回多个值

// 数组
function fun() {
    return [1, 2, 3];
}
var [x, y, z] = fun();
console.log(x); // 1
console.log(y); // 2


 

// 对象
function fun() {
    return {
        id: '007',
        name: 'canan',
        age: 28
    }
    var {id, name, age} = fun();
    console.log(id);
}


3、函数参数的定义

// 参数是一组有次序的值
function([x, y]) {
    // x = 100
    // y = 200
};
fun([100, 200]);
// 参数是一组无次序的值
function fun({id, userName, age}) {
    // id = '007'
    // userName = 'conan'
    // age = 28
}
fun({id: '007', userName: 'conan', age: 28});



4、提取json数据

 

var jsonData = {
    id: "007",
    userName: "conan",
    age: 28,
    score: {Chinese: 98, English: 107}
}
console.log(jsonData);
let {id: number, userName, age, Chinese: Chinese} = jsonData
console.log(number);
console.log(userName);
console.log(score.Chinese)


5、函数参数的默认值

// 对象的解构赋值传值,好处:避免了在函数体内部再写var foo = config.foo || 'default foo' 这样的语句
jQuery.ajax = function(url, {
    async = true,
    beforeSend = function() {},
    cache = true,
    complete = function() {},
    crossDomain = false,
    global = true,
    // ...more config
}) {
    // ... do stuff
}



6、遍历map结构

 

var map = new Map();
map.set('id', '007');
map.set('age', 28);
console.log(map); // Map(2) {"id" => "007", "age" => 28}
console.log(typeof map); // object
for (let [key, value] of map) {
  console.log(`${key}is${value}`);
}
// 获取键名
for(let [key] of map) {
    console.log(key); // id, age
}
// 获取值
for (let [, value] of map) {
    console.log(value); // 007, 28
}


7、输入模块的指定方法
(1)require.js 智能模块

// 先引入require.js
// requirejs的应用
const {SourceMapConsumer, SourceNode} = require('source-map');



另外一个视频中的es6
1、

// tagged-template
let dessert = 'a';
let drink = 'b';
let breakfast = kitchen `今天的早餐是 ${dessert} 与 ${drink} !`
function kitchen(strings, ...values) {
    console.log(strings); // 今天的早餐是  与   !
    console.log(values); // a b
}

// string-function
console.log(
    breakfast.startWith('今天'); // 以什么字符串开头
    breakfast.endWith('!'); // 以什么字符串结尾
    breakfast.includes('今天'); // 包含什么字符串
)



2、function name :得到函数名

let breakfast = function latestBreakfast() {}
console.log(breakfast.name); // latestBreakfase



3、object-literal

let dessert = ‘a';
let obj = {
    dessert,
    drink = 'b',
    breakfast() {} // 等价于breakfast: function() {}
}



4、

console.log(+0 == -0); // true
console.log(+0 == -0); // true
console.log(NaN == NaN); // false
Object.is (+0, -0); // false
Object.is (NaN, NaN); // true



5、Object.setPrototypeOf可以在创建对象之后改变对象的prototype
Object.getPrototypeOf可以设置对象的prototype

let breakfast = {
    getDrink() {return 'a';}
}
let dinner = {
    getDrink() {return 'b';}
}
let sunday = Object.create(breakfast);
console.lob(Object.getPrototypeOf(sunday) === breakfast); // true

Object.setPrototypeOf(sunday, dinner);
console.log(Object.getPrototypeOf(sunday) === breakfast); // false



6、es6的__proto__可以设置对象的prototype

let sunday = {
    __proto__: breakfast
}
console.log(Object.getPrototypeOf(sunday) === breakfast); // true



7、

let sunday = {
    __proto__: breakfast,
    getDrink() {
        return super.getDrink() + '1'; // super.getDrink()就是breakfast.getDrink()
    }
}
console.log(sunday.getDrink()); // a1



8、Iterators:迭代器
(1)特点:①每次执行的时候会返回一个对象,一个是value, 一个是done。
②迭代器里有next方法,执行这个方法会返回一个对象,对象有value, done属性。如果没有迭代的里,value就是undefined, done就是true了
(2)手写一个迭代器

 

 function chef(foods) {
    let i = 0;
    return {
      next() {
        let done = (i >= foods.length);
        let value = !done ? foods[i++] : undefined;
        return {
          value,
          done
        }
      }
    }
  }
  let wanghao = chef([1, 2]);
  console.log(wanghao.next()); // {value: 1, done: false}
  console.log(wanghao.next()); // {value: 2, done: false}
  console.log(wanghao.next()); // {value: undefined, done: true}



9、genarators
手工创建迭代器比较麻烦,可以用generator创建生成器

function* chef() {
    yield 'a';
    yield 'b';
}
let wanghao = chef(); // 利用生成器创建迭代器
console.log(wanghao.next()); // {value: 'a', done: false};


 

let chef = function* (foods) {
    for(var i = 0; i < foods.length; i++) {
        yield foods[i];
    }
}
let wanghao = chef(['a', 'b']);



10、class类里有get, set方法
11、静态化类:不需要实例化类就能使用的方法。可以用static关键词

 

 class Chef {
    static cook(food) { // 使用了static  // 如果cook前面没有static,执行Chef.cook('a')则会报错:Chef.cook is not a function
      console.log(food);
    }
  }
  Chef.cook('a'); // 不用new Chef



12、Set:add size has delete forEach clear

let desserts = new Set('123');
desserts.add('4');
desserts.add('4');
console.log(desserts); // Set(4){'1', '2', '3', '4'}
console.log(desserts.size); // 4
console.log(desserts.has('1')); // true

desserts.delete('2');
console.log(desserts); // Set(3){'1', '3', '4'}
desserts.forEach(dessert => {
  console.log(dessert);
})
desserts.clear();
console.log(desserts); // Set(0){}



13、Map:set size get delete has forEach clear

let food = new Map();
console.log(food);

let fruit = {}, cook = function() {}, dessert = '糕点';
food.set(fruit, 'a'); // 往map里添加名字
food.set(cook, 'b');
food.set(dessert, 'c');

console.log(food.size); // 3
console.log(food.get(fruit)); // a
  
food.delete(dessert);
console.log(food.has(dessert)); // false
  
food.forEach((value, key) => {
  console.log(`${key} = ${value}`);
})
food.clear();
console.log(food); // Map(0) {}



14、module:es6需要借助webpack或jspm

<script src="node_module/babel-core/browser.js"></script>
<script src="node_mobule/babel-core/browser-polyfill.js"></script>
<script src="jspm_package/system.js"></script>
<script src="config.js"></script>
<script>
    System.import('script');
</script>
<script src="script.js" type="text/babel"></script>



(1)可以到处的有:变量,函数,类等等。
(2)导出默认的东西不需要大括号{},
import {food, chef} from '';
import food from ''; // food是默认导出的东西

export {dinner as default}; // 将dinner这个模块作为默认要导出的东西
--------------------- 
作者:aSuncat 
来源:CSDN 
原文:https://blog.csdn.net/aSuncat/article/details/88568483 
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值