ECMAScript Harmony
1.常量:const;
const FLAG=true; FLAG = false; alert(FLAG);//true
2.块级作用域:let:定义的变量在定义它的代码块之外没有定义:
for(var i = 0;i<10;i++){ } alert(i);//10 for(let i=0;i<10;i++){ } alert(i);//error i没有定义
创建let语句,在其中定义只能在后续代码块中使用的变量:
var num=5; let(num=10,mul=2){ alert(num*mul);//20 } alert(num);//5
3.生成器:一个对象,每次能生成一系列值中的一个:
function myNumbers(){ for(var i =0;i<10;i++){ yield i*2; } } var generator=myNumbers(); try{
while(true){ document.write(generator.next()+"<br/>"); } }catch(ex){ //...... }finally{ generator.close() ; }
对于使用yield操作符返回值得函数,调用它时就会创建并返回一个新的Generrator实例,然后调用next()方法就能取得生成器的第一个值;
4.迭代器:也是一个对象,能迭代一些值并每次返回其中一个值,用next()方法取值;为对象创建迭代器可调用Iterator构造函数:
var arr=[1,2,3,4,5];//数组或者对象,每次next返回一个数组;迭代数组时返回第一个元素是元素值的索引,第二个元素是元素值;迭代对象时第一个元素是属性名,第二个元素是属性值; var iterator=new Iterator(arr); try{
while(true){ let value=iterator.next(); document.write(value.join(":")+"<br/>"); } }catch(ex){ //...... }
如果只想让next方法返回对象的属性名或者数组的索引值,可以在创建迭代器时为Iterator构造函数传入第二个参数:true;
5.数组领悟:
//原始数组 var numbers=[0,1,2,3,4,5,6,7,8,9]; //把所有元素复制到新数组 var duplicate=[i for each(i in numbers)]; //只把偶数复制到新数组 var exens = [i for each(i in numbers) if (i % 2 == 0)]; //把每个数乘以2后的结果放到新数组 var doubled=[i *2 for each (i in numbers)]; //把每个奇数乘以3后的结果放到新数组 var thipledOdds=[i*3 for each (i in numbers) if (i %2 > 0)];
6.代理对象:一个表示接口的对象,对他的操作不一定作用在代理对象本身。创建代理对象可以使用Proxy.create()方法,传入一个handler(处理程序)对象和一个可选的prototype(原型)对象:
var proxy=Proxy.create(handler);
//创建一个以Object为原型的代理对象 var proxy=Proxy.create(handler,Object);
handler对象包含用于定义捕捉器的属性,捕捉其本身就是函数,用于处理(捕捉)原生功能,以便该功能能够以另一种方式来处理。
基本捕捉器:
getOwnPropertyDescriptor;getPropertyDescriptor; getOwnPropertyName;getPropertyName;defineProperty;delete;fix;
派生捕捉器:
has(在对象上使用in操作符:“name” in object);hasOwn(在代理对象上使用hasOwnProperty);get;set;enumerate;keys;
创建代理函数:
var proxy=Proxy.createFunction(handler,function(){},function(){});
7.映射与集合:
简单映射的基本API包括get(),set(),delete();键可以是原始值也可以是引用值;
集合中只有键没有与键关联的值;add(),has(),delete():
8.weakMap:ECMAScript中唯一一个能让你知道什么时候对象完全解除引用的类型。与简单映射相似,区别是它的键必须是对象:
var key={}; var map=new WeakMap(); map.set(key,"hello"); key=null;//解除了对键的引用,从而删除该值
9.模块:每个模块都包含着独立于其他模式的特定独一无二的功能:
module MyModule{ //公开成员 export let myObject={}; export function hello(){ alert("hello"); }; //隐藏成员 function goodbye(){ alert("goodbye"); } }
导入模块要使用import命令:
//只导入myobject import myobject from MyModule ; //导入所有公开的成员 import * from MyModule;
外部模块:通过模块所在外部文件的URL,也可以动态加载模块,为此首先要在模块声明后加上外部文件的URL,然后再导入模块文件。
module MyModule from "mymodule.js";
import myobject from MyModule;
这样会通知JavaScript引擎下载mymodule.js文件然后从中加载名为MyModule的模块,这个调用会阻塞进程,也就是说JavaScript引擎在下载完外部文件并对其求值之前不会处理后面的代码;如果指向包含模块中对外公开的某些成员不想加载整个模块,可以使用:
import myobject from "mymodule.js";
总之,模块就是一种组织相关功能的手段,而且能够保护全局作用域不受污染。