ES6初始记录(较乱)

2016-11-29  本文已影响0人  shanshanfei

转码器:babel,允许用ES6的语法来写程序,而不用考虑现有环境是否支持。

EcmaScrip是规范,JavaScript是实现。
Es6包含ecma2015 ecma2016 ecma2017,一般是指ecma2015。

let 和 const

顶层对象的属性:
ES5 顶层对象的属性与全局变量是等价的。
ES6 开始全局变量不都是顶层对象的属性了,只有var、function定义的才算,let、const、class定义的不算顶层对象的属性。

const与let一样:

ES5声明变量有2种方式:var + function
ES6声明变量有6种方式:var + function + let + const + import + class

ES5只有全局+函数作用域,无块级作用域(导致:内部变量覆盖外部变量、for计数变量外泄为外部变量等)
ES6 let只在块级作用域内有效,可以替换立即执行函数了IIFE。{let a;…..}

ES5不允许在块级作用域中声明函数,但是浏览器真正实现是:允许声明函数,而且会提升至作用域前面。
ES6明确允许在块级作用域中声明函数,而且浏览器环境和非浏览器环境表现不同:
- 浏览器环境:相当于var声明,会提升(提升至所在全局||函数作用域头部),赋值延后(函数声明会提升至所在块级作用域头部)。
- 非浏览器环境:相当于let声明,不会提升,只在当前块级作用域有效。
所以:为了表现一致,尽量不在块级作用域内声明函数,若必须声明,则使用 函数表达式方式 ,而非函数声明方式。

let为js新增了块级作用域,声明变量,只在当前代码块内有效。
立即执行函数表达式IIFE(Immediately-Invoked Function Expression):(function(){})();

变量的解构赋值

解构赋值的规则:只要等号右边不是对象,就现将其转换成对象。
解构赋值:数组、对象、字符串、数值、布尔值、函数参数等的解构赋值。

** 对象的解构赋值 **
模式不会被赋值,被赋值的是模式后面的变量:

let {loc: first, glo:last} = {loc:123, glo: 456};//loc和glo是模式,first和last才是真正赋值的变量

对于已经声明的变量进行解构赋值时,需要加上小括号,因为不加的话,js会将行首的花括号解释为代码块,引起语法错误。

let x;
{x} = {x:1}; //SyntaxError: syntax error
({x} = {x:1}); //正确

解构赋值的几个好处:

  1. 提取JSON数据的值;
  2. 函数参数定义默认值;
  3. 提取某对象或模块的方法;

字符串的扩展

对字符串进行操作的时候,要注意常规字符(两字节)和辅助字符(四字节)的区别。
unicode是世界上所有的字符集,是一种二进制的表示方法,但是并没有规定存储方式。UTF-8和UTF-16、UTF-32就是其具体的存储实现,具体区别可以阅读阮一峰老师的两篇文章,参考:

字符串的扩展重点:

正则的扩展

正则表达式新增flags属性,返回修饰符

数值的扩展

数组的扩展

JS中数组的迭代方法:

方法 举例
forEach:对数组中的每一项执行操作 arr.forEach(function(v, i, arr){return v+1;})
every:每一项都满足某条件则返回true if(arr.every(function(v,i,arr){return v > 2;})){}
some:只要有一项满足某条件则返回true if(arr.some(function(v,i,arr){return v > 2;})){}
map:对数组每一项进行操作,返回数据组成新数组返回 var newArr = arr.map(function(v, index, arr){return v*2;});
filter: 对数组进行过滤,满足条件的项组成新数组返回 var newArr = arr.filter(function(v, index, arr){return v > 10;});
reduce:对数组的相邻两项进行操作 var sum = arr.reduce(function(sum, item){return sum+item;}, 0)
includes:数组是否包含某值 if(arr.includes(2)){}

函数的扩展

对象的扩展

var o = Object.create({ x: 1, y: 2 });//x y算继承属性
o.z = 3;

let { x, ...m } = o;
x // 1---单纯的结构赋值
m // {z: 3} --- 扩展运算中的解构赋值
for...in //返回对象自身和继承的可枚举属性
Object.keys() //返回对象自身可枚举属性
Object.getOwnPropertyNames() //返回对象自身所有属性(包括不可枚举)
Object.getOwnPropertySymbols() //返回对象自身Symbols属性
Reflect.ownKeys() //返回对象自身symbol类型和字符串类型的属性(不管是否可枚举)
方法 适用范围 描述
for...in 数组、对象 获取可枚举的实例和原型属性名(返回键名)
Object.keys() 数组、对象 返回可枚举的实例属性名组成的数组
Object.getOwnPropertyNames() 数组、对象 返回除原型属性以外的所有属性(包括不可枚举的属性)名组成的数组
for…of 可迭代对象(Array Map Set等) 返回属性值(返回键值)
Reflect.ownKeys() 对象自身的所有属性,包含symbols属性和不可枚举属性

Symbol

ES6新增原始数据类型Symbol,表示独一无二的值(对象属性名可以保证不会冲突)。Symbol给我感觉用处不是很顺畅,很别扭的感觉。

Symbol('aa') === Symbol('aa') //false
Symbol.for('aa') === Symbol.for('aa') //true
Symbol.keyFor(Symbol.for('aa')) //'aa'
Symbol.keyFor(Symbol('aa'))//undefined

Map和Set数据结构

数据集合:ES5 -> Array+Object ,ES6 -> Map+Set

--- Set

类似于没有重复值的数组。键名和键值完全一样。

//操作方法 add delete has clear
var set = new Set([1,2,3,2,3]);//[1,2,3]
set.add(4);//[1,2,3,4]
set.size;// 4
set.delete(1);
set.has(2);
set.clear();//清空

//遍历方法 .keys() .values() .entries() .forEach()
let set = new Set(['red', 'green', 'blue']);

for (let item of set.keys()) {
  console.log(item);
}
// red
// green
// blue

for (let item of set.values()) {
  console.log(item);
}
// red
// green
// blue

for (let item of set.entries()) {
  console.log(item);
}
// ["red", "red"]
// ["green", "green"]
// ["blue", "blue"]

set.forEach((value,key,set) =>console.log(value+':'+key) );
--- WeakSet

与set类似,但是只保存对象类型的数据,是对象类型数据的弱引用,目的是防止内存泄漏。常用方法有:add has delete,无法遍历

--- Map
// 操作方法 set get has delete clear
var map = new Map([ ['name', 'fss'], ['age', 27] ]);
map.set('job', 'computer').set('xx', 'aa');
map.get('xx');//'aa'
map.size;//3 条目个数
map.has('job');//true

//遍历方法 map.keys() .values() .entries() forEach()
--- WeakMap

与Map结构类似,键名只能是对象类型,弱引用,防止内存泄漏。常用方法:get set has delete,无法遍历。

Proxy

对对象的一层代理拦截,修改对象操作的默认行为。

//handler为{}时,代表无拦截效果;handler内部定义了一些内置的拦截方法:get set apply construct等
var proxy = new Proxy(target, handler);

var handler = {
  get: function(target, name) {
    if (name === 'prototype') {
      return Object.prototype;
    }
    return 'Hello, ' + name;
  },

  apply: function(target, thisBinding, args) { //一般函数调用时拦截函数
    return args[0];
  },

  construct: function(target, args) {//构造函数调用时拦截函数
    return {value: args[1]};
  }
};

var fproxy = new Proxy(function(x, y) {
  return x + y;
}, handler);

fproxy(1, 2) // 1
new fproxy(1,2) // {value: 2}
fproxy.prototype === Object.prototype // true
fproxy.foo // "Hello, foo"

Reflect

Promise

var promise = new Promise(resolve, rejected);//新建后立即执行,无法中断
promise.then(resolveFunc, rejectedFunc)
.then(resolveFunc)//链式写法
.catch(function(){})//状态为rejected时执行,resolveFunc执行出错时也执行

遍历器Iterator接口

为各种不同的数据结构(Array、Object、Map、Set)提供一种统一的访问机制(即for...of)。只要部署了Symbol.iterator(默认指向该对象的遍历器接口,必须要有next方法)属性的数据结构,就被称为部署了遍历器接口。

Generator函数

ES6提供的异步编程解决方案,可以理解成一个状态机,封装了多个内部状态。

function* generatorFunc(){//带有星号*
    //some code 
    yeild 'status1';//函数内部可以用yeild定义状态
    //some code 
    yeild 'status2';
    //some code 
    yeild 'status3';
    //some code 
    return 'status4'; //可以没有
}
var geneFunc = generatorFunc();
geneFunc.next();//{value:'status1', done: false} 
geneFunc.next();//{value:'status2', done: false} 
geneFunc.next();//{value:'status3', done: false} 
geneFunc.next();//{value:'status4', done: true}
geneFunc.next();//{value:undefined, done: true}  
console.log('Hello' + yield); // SyntaxError
console.log('Hello' + yield 123); // SyntaxError

console.log('Hello' + (yield)); // OK
console.log('Hello' + (yield 123)); // OK

foo(yield 'a', yield 'b'); // OK 函数参数和赋值时,可以不用圆括号
let input = yield; // OK
function* foo(x) {
    var y = 2 * (yield (x + 1));
    var z = yield (y / 3);
    return (x + y + z);
}

var a = foo(5);
a.next() // Object{value:6, done:false}
a.next() // Object{value:NaN, done:false}
a.next() // Object{value:NaN, done:true}

var b = foo(5);
b.next() // { value:6, done:false }
b.next(12) // { value:8, done:false }
b.next(13) // { value:42, done:true }

二十三:SIMD

(目前JS引擎基本不支持,可以仅作了解)

SIMD:单指令 多数据(single instruction / mutiply data)
SISD:单指令 单数据(single instruction / single data)--- JS默认运算模式

SIMD是js操作CPU对应指令的接口,完成多个数据的运算,广泛用于3D图形运算、物理模拟等运算量超大的项目之中。

SIMD提供12种数据类型,总长度都是128个二进制位。

Float32x4:四个32位浮点数
Float64x2:两个64位浮点数

Int32x4:四个32位整数
Int16x8:八个16位整数
Int8x16:十六个8位整数

Uint32x4:四个无符号的32位整数
Uint16x8:八个无符号的16位整数
Uint8x16:十六个无符号的8位整数

Bool32x4:四个32位布尔值
Bool16x8:八个16位布尔值
Bool8x16:十六个8位布尔值
Bool64x2:两个64位布尔值

每种数据类型被x符号分隔成两部分,后面的部分表示通道数,前面的部分表示每个通道的宽度和类型。比如,Float32x4就表示这个值有4个通道,每个通道是一个32位浮点数。
利用SIMD的一些静态方法,可以完成一些运算,具体就不展开介绍了,可以参考链接:http://es6.ruanyifeng.com/#docs/simd

上一篇下一篇

猜你喜欢

热点阅读