在NDN的JavaScript Guide里,Array和Map,Set都属于collections of data。它们的区别就是,Array是ordered by an index value, Map,Set是ordered by a key。Map类似无属性的Object,Set类似Array,但是数据存取效率更高,适合大量数据。Map and Set的遍历顺序就是插入数据的顺序,先插入的先出来(FIFO—first in first out)。

Map and Set 用new生成实例的时候,构造函数参数只有是可遍历对象才能转换为集合数据,注意Map传入的可遍历对象的迭代器方法返回的value必须是能转换成key-value pair形式。示例代码:

function* gen() { yield 1; }
let g = gen();
let mapData = new Map(g); //TypeError: Iterator value 1 is not an entry object

function* gen() { yield [1]; }
let g = gen();
let mapData = new Map(g);
console.log([...mapData]); //[ [ 1, undefined ] ]

function* gen() { yield {"1":1}; }
let g = gen();
let mapData = new Map(g);
console.log([...mapData]); //[ [ undefined, 1 ] ]

var myArray = ["value1"];
var mySet = new Set(myArray);
let mapData = new Map(mySet[Symbol.iterator]()); //TypeError: Iterator value value1 is not an entry object

var kvArray = [["key1", "value1"]];
var myMap = new Map(kvArray);
let mapData = new Map(myMap[Symbol.iterator]());
console.log([...mapData]); //[ [ 'key1', 'value1' ] ]
Map用set方法插数据,key相等的只插一次。把Map自定义Key的行为去掉,就是Set,Set用add方法插值,在一个Set数据里相等的值只插一次。Map,Set的相等判断规则和Object.is()一样。

遍历Map得到数据是数组[key, value]形式。遍历方法一般用for…of ,Map写法for (let [key, value] of mapData){},Set写法for (let item of setData){};二般用迭代器,用Map,Set实例的迭代器方法,比如maporset[Symbol.iterator]() 可以得到这个实例的迭代器,用迭代器的next()方法可以按FIFO顺序单步得到集合的数据。除了遍历外,Map还可以通过get方法,Set不知道key没有get方法。

WeakMap,WeakSet是为了更无脑的GC创造的,就是弱引用的Map和Set,它们不是可遍历对象,不能遍历。Map的键名和Set的值只能是Object类型。

为了块级词法环境的具体实现,于是有了let和const,为什么不直接重新定义var,而搞个let,为了One JavaScript.

let和const声明关键字用来定义变量,它们的存活范围仅限于当前运行的EC的词法环境。在它们的词法环境实现的时候,这些变量被创建,但是没有任何方式获得它们,直到这些变量的词汇绑定器计算完成。在词汇绑定计算的时候,一个变量定义被一个词汇绑定器和初始化器根据它的初始化赋值表达式完成赋值。完成以上步骤变量才算创建完成。在词汇绑定器计算的时候,如果用let声明的变量没有赋值表达式,词汇绑定器会给这个变量赋值undefined.

在标准文档中,let and const的描述比var的描述,多了but may not be accessed in any way until。就是在完成赋值表达式之前不能使用,也叫暂存死区TDZ (Temporal Dead Zone) 。有人说let和const不存在变量提升,其实是错误的,只是限制accessed而已。标准明确说了The variables are created when their containing Lexical Environment is instantiated but may not be accessed。

新加的词法环境,都存在TDZ,ECMAScript的词法环境机制决定了标识符都会在词法分析阶段就绑定,也叫做提升,但是let,const,class,函数形参,模块在其语句执行完成前都不能使用。当然也可以改变提升的定义,把TDZ的情况排除到提升的范围外,比如提升就是指以前var那种表现,那之后新加的词法环境确实都不存在提升问题。

https://tc39.github.io/ecma262/#sec-declarations-and-the-variable-statement
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let
let是一个更严格的var。(忘了var吧,let值得拥有)

let继承var的规范,如果var规范和以下规范冲突,则采用以下规范。

用let定义的全局范围变量,不会成为全局对象的属性。

let可以把变量的作用范围限制在块级。块级域,用一对花括号限定的区域,通常特指流程控制语句块 ,如 if,for等。for语句的圆括号部分和花括号部分属于同一块级域。

用let定义的变量,在变量所属作用域内,不包括嵌套域,再用let定义一个同名变量将引起 TypeError。

用let定义的变量,在变量所属作用域外部,使用它将引起 ReferenceError。

用let定义的变量,在定义语句之前,使用它将引起 ReferenceError。

const是一个更严格的let。

const继承let的规范,如果let规范和以下规范冲突,则采用以下规范。

const定义的变量,必须初始化赋值,只能赋值一次,以后不能更改,这就是常量。建议常量名大写。

如果常量的值是指向内存的地址,常量只是不能再通过赋值改变引用地址,管不着引用对象。

Note: => is not an operator, but the notation for Arrow functions.注意=>不是一个运算符,它不过是箭头函数的特有符号。箭头函数的核心就是=>符号,主要是精简函数表达式的写法,特别在函数只有一个参数和函数体只有一个分号的时候,可以省略function和return 关键字,圆括号,花括号,比如var foo = x => x; 够简单吧,呵呵,写起来爽,读起来就没那么直观了,就和用逻辑或代替if else的变量赋值表达式一样,var bar = x || 1; 而且在有多个参数和函数体有多个语句的时候,就只比标准写法省略个function关键字。当然还有this和arguments的特性,但是不能指定this值则更限制了它的使用范围。开发者显式指定this值是个好习惯也更安心,我更喜欢接近人类语言的代码书写方式。

一个ArrowFunction 并不能给arguments, super, this, or new.target定义本地绑定local bindings。在an ArrowFunction内arguments, super, this, or new.target的值引用必须在包裹箭头函数的外层词法环境中进行绑定。通常this会是句法上包裹箭头函数的那个函数的词法环境。箭头函数没有自己的词法环境,所以多个嵌套的箭头函数,它们的this都是最外层那个有独立词法环境的句法结构体的环境。

https://tc39.github.io/ecma262/#sec-arrow-function-definitions-runtime-semantics-evaluation
函数参数的新特性,Default parameters就是可以在函数声明的时候给圆括号里的形参使用赋值表达式,注意在函数调用时,默认参数赋值语句要比花括号里面的语句先执行,执行顺序是从左到右。Rest parameters 剩余参数,语法形式是spread operator …加形参名。可以用来取代arguments。 rest parameters are Array instances。

对象中函数方法的新写法,就是省掉冒号:和function关键字…

var obj = {
        // 现在不再使用function关键字给对象添加方法
        // 而是直接使用属性名作为函数名称。
        method(args) { ... },
        // 只需在标准函数的基础上添加一个“*”,就可以声明一个生成器函数。
        *genMethod(args) { ... },
        // 借助|get|和|set|可以在行内定义访问器。
        // 只是定义内联函数,即使没有生成器。
        // 注意通过这种方式装载的getter不能接受参数
        get propName() { ... },
        // 注意通过这种方式装载的setter至少接受一个参数
        set propName(arg) { ... },
        // []语法可以用于任意支持预计算属性名的地方,来满足上面的第4中情况。
        // 这意味着你可以使用symbol,调用函数,联结字符串
        // 或其它可以给property.id求值的表达式。
        // 这个语法对访问器或生成器同样有效,我在这里只是举个例子。
        [functionThatReturnsPropertyName()] (args) { ... }
    };
this 是一个与EC密切相关的特殊对象,因此,它可以称为EC对象(context object)。任何对象都可以做为上下文中的 this 的值。

this 是EC的一个属性。this 与EC类型紧密相关,其值在进入EC阶段就确定了,并且在执行代码阶段不能被改变。

在全局EC中,this 就等于全局对象本身。在函数上下文的情况下,对函数的每次调用,其中的 this 值可能是不同的。函数上下文中 this 的值由调用者(caller)提供,并由调用表达式的形式确定(函数调用的语法)。相同的函数,调用形式和调用者不同,this的值也可能不同。可以使用Function.prototype.bind(),Function.prototype.call(),Function.prototype.apply()方法指定函数调用时内部的this对象。

this在严格模式下有特有的规则。

Template literals 模板字面量通常用来替代以前那种字符串+变量或函数表达式的拼接写法。Tagged template literals标签模板字面量,就是为模板字面量提供自定义行为处理函数Tag functions。模板字面量相关规则和形式,有点像以前String.prototype.replace()的$和replacement function 。

模块 Modules, 新Statements,export和import,本身没什么好说的,反正在新标准出来之前,已经在大量使用了,去学webpack之类的东西吧。

学习ECMAScript标准和具体实现-JavaScript的更多相关文章

  1. SAP ABAP学习路线图--标准教程

    SAP ABAP学习路线图--标准教程 摘自:http://www.cnblogs.com/clsoho/archive/2010/07/05/1771400.html

  2. HTML学习笔记——标准网页设计+使用CSS、Javascript

    一.标准网页设计 1.标准网页概述: 标准网页设计要遵循,内容与表现相分离.   内容 + 表现 = 页面  ---  即 :XHTML + CSS = PAGE 内容与变现相分离,也就是内容使用HT ...

  3. 《ECMAScript标准入门》第二版读书笔记

    title: <ECMAScript标准入门>第二版 date: 2017-04-10 tags: JavaScript categories: Reading-note 2015年6月, ...

  4. 学习笔记 第十五章 JavaScript基础

    第15章   JavaScript基础 [学习重点] 了解JavaScript基础知识 熟悉常量和变量 能够使用表达式和运算符 正确使用语句 能够掌握数据类型和转换的基本方法 正确使用函数.对象.数组 ...

  5. C语言学习008:标准错误

    在上一节中的数据文件中(C语言学习007:重定向标准输入和输出),如果文件中的数据包含非法数据,如何让程序显示一条错误的提示消息呢?就需要用到标准错误 #include <stdio.h> ...

  6. 脚本学习python和linux-shell和jQuery(javascript)

    使用脚本可以方便管理,使用计算机. 打算学脚本来更好地用计算机系统,特别是Linux. 学python因为它开源,而且是C家族的语言,本来也是课程需要,再加上它确实很好,所以非常主打,之前看过perl ...

  7. ExtJS学习-----------Ext.Array,ExtJS对javascript中的Array的扩展

    关于ExtJS对javascript中的Array的扩展.能够參考其帮助文档,文档下载地址:http://download.csdn.net/detail/z1137730824/7748893 因为 ...

  8. Python学习笔记第二十四周(JavaScript补充)

    目录: 一.JS补充 1.函数类型 2.string对象 3.instanceof 4.Array 数组对象 5.Date对象 6.RegExp 正则表达式 7.Math对象 二.BOM补充 1.wi ...

  9. HTML5学习笔记(十三):JavaScript函数

    函数定义 在JavaScript中,定义函数的方式如下: function abs(x) { if (x >= 0) { return x; } else { return -x; } } 上述 ...

随机推荐

  1. web框架的本质(使用socket实现的最基础的web框架、使用wsgiref实现的web框架)

    import socket def handle_request(client): data = client.recv(1024) client.send("HTTP/1.1 200 OK ...

  2. .linux基础命令三

    一. 两台服务器免密登录: 1. 生成密钥 ssh-keygen的命令手册,通过”man ssh-keygen“命令查看指令: 通过命令”ssh-keygen -t rsa“创建一对密匙,包括公匙和私 ...

  3. 事件对象e的实现原理

    转自:https://segmentfault.com/q/1010000007337410?_ea=1313467 事件对象传递原理 1.前置知识回顾 在讲传递原理前,我们先看看普通函数是如何传递参 ...

  4. IE9的兼容性

    /* 解决IE9表格错位 */ .el-table--border th:last-of-type.gutter { display: table-cell !important; width: 50 ...

  5. git submodule删除多余模块

    rm -rf 子模块目录 删除子模块目录及源码 vi .gitmodules 删除项目目录下.gitmodules文件中子模块相关条目 vi .git/config 删除配置项中子模块相关条目 rm ...

  6. Robot Framework 源码阅读 day1 run.py

    robot里面run起来的接口主要有两类 run_cli def run_cli(arguments): """Command line execution entry ...

  7. vue.js 笔记

    <!-- 多层for循环 --> <ul> <li v-for="(ite,key) in list2"> {{key}}-------{{it ...

  8. lvm分区创建和扩容

    shell> fdisk /dev/xvdb #### 选择磁盘 Command (m for help): m #### 帮助 Command action a toggle a bootab ...

  9. Django中ifequal 和ifnotequal的使用

    Django中{% ifequal A B %} 用来比较A和B两个值是否相等,{% ifnotequal A B %}` 用来比较A和B两个值是否不相等..如: {% ifequal user cu ...

  10. 关于DNS

    一.什么是DNS DNS 是域名系统 (Domain Name System) 的缩写,它是由解析器和域名服务器组成的.域名服务器是指保存有该网络中所有主机的域名和对应IP地址,并具有将域名转换为IP ...