TypeScript 学习笔记3: ECMAScript 2015 的新特性

来源:互联网 发布:网络奇葩歌词找歌 编辑:程序博客网 时间:2024/06/05 18:02

原文链接:https://leanpub.com/essentialtypescript/read#ecmascript-features

这一章讲的东西都是 “语法糖” —— syntactic sugar,就是说,它们并没有提供新的功能,只是提供了一种简便的写法。

1. Optional Parameters

var container = document.getElementById('container');function countdown(initial, final, interval) {    var current = initial;    while(current > final) {        container.innerHTML = current;        current -= interval;    }}countdown(10, 0, 1);
这是一个循环递减函数。在大部分情况下,我们都会让 final等于0, interval等于1。可以给参数设置默认值:

function countdown(initial, final=0, interval=1) {    var current = initial;    while(current > final) {        container.innerHTML = current;        current -= interval;    }}countdown(10);
这样,在调用时,后两个参数就可以省略了。

看看tsc编译出来的es5代码:

var container = document.getElementById('container');function countdown(initial, final, interval) {    if (final === void 0) { final = 0; }    if (interval === void 0) { interval = 1; }    var current = initial;    while (current > final) {        container.innerHTML = current;        current -= interval;    }}

很熟悉哈。以前,自己也一直是这么写的。

2. Template Strings

var todo = {    id: 123,    name: "Pick up drycleaning",    completed: true}var displayName = `Todo #${todo.id}`;
程序运行时,最后一行的 ${todo.id} 会被替换成 123。

再看一个复杂的例子:

var container = document.getElementById('container');var todo = {    id: 123,    name: "Pick up drycleaning",    completed: true}container.innerHTML =  `    <div todo='[[Todo ID]]' class="list-group-item}">        <i class="[[ If Todo is complete, then "hidden" ]] text-success glyphicon glyphicon-ok"></i>        <span class="name">[[Name]]</span>    </div>`
注意:

    1. 用双重方括弧 [[ ]] 包起来的,都是我们希望动态替换的。

    2. container.innerHTML 后面,多行字符串可以用反引号(数字1左边的按键)包起来,这种字符串中单引号和双引号都不需要转义。

${ } 中,不仅可以包含变量,还可以包含任意语句。所以,动态替换的代码可以这么写:

container.innerHTML =  `    <div todo='${todo.id}' class="list-group-item}">        <i class="${todo.completed ? "" : "hidden"} text-success glyphicon glyphicon-ok"></i>        <span class="name">${todo.name}</span>    </div>`
看一看tsc编译出来的ES5代码:

container.innerHTML = "\n    <div todo='" + todo.id + "' class=\"list-group-item}\">\n        <i class=\"" + (todo.completed ? "" : "hidden") + " text-success glyphicon glyphicon-ok\"></i>\n        <span class=\"name\">" + todo.name + "</span>\n    </div>\n";

3. Let and const

for(var x = 0; x <= 5; x++) {    var counter = x;}console.log(counter);
输出什么? 5

大括号不能生成新的作用域,在js中,只有function可以定义新的作用域。

let 可以解决这个问题。

for(var x = 0; x <= 5; x++) {    let counter = x;}console.log(counter);

这段代码运行会出错,let 使 counter的作用域限制在for循环内部。

const counter = 1;counter = 3;

这段代码运行会出错,const定义了常量,常量不可修改。

4. For .. of Loops

for .. in 遍历的是数组的索引

var array = [ "Pick up drycleaning",  "Clean Batcave", "Save Gotham" ];for(var index in array) {    var value = array[index];    console.log(`${index}: ${value}`);}
for .. of 可以直接遍历数组中的值
var array = [ "Pick up drycleaning",  "Clean Batcave", "Save Gotham" ];for(var value of array) {    console.log(value);}

5. Arrow Functions

js 中的 this 变量是个很怪异的东西,看个例子:

var container = document.getElementById('container'); function Counter(el) {    this.count = 0;    el.innerHTML = this.count;    el.addEventListener('click', function () {        this.count += 1;        el.innerHTML = this.count;    });} new Counter(container);
把这段代码复制到 TypeScriptTodo 工程的 app.ts 文件中,保存。 确保 tsc -w 正在运行。

打开一个命令行窗口,切换到 TypeScriptTodo 目录下,运行: lite-server。

浏览器会自动打开,页面上显示0。点击页面,呃,本以为0会变成1,结果却是 NaN。这是因为event handler 不是 Counter 的成员函数,在这个function内部,this指的是js环境的全局对象(在node.js环境中是global,在browser环境中是window)。

为了解决这个问题,通常我们使用这种模式:

    let _this = this;    el.addEventListener('click', function () {        _this.count += 1;        el.innerHTML = _this.count;    });
这种写法看起来很笨拙,ES6提供了一种新的语法(arrow function):

    el.addEventListener('click', () => {        this.count += 1;        el.innerHTML = this.count;    });
把 "function()" 改成了 "() => " 。

看一下tsc编译后的代码:

var container = document.getElementById('container');function Counter(el) {    var _this = this;    this.count = 0;    el.innerHTML = this.count;    el.addEventListener('click', function () {        _this.count += 1;        el.innerHTML = _this.count;    });}new Counter(container);
原创粉丝点击