JavaScript 1.7

<script>元素的type属性设置为”application/javascript;version=1.7”

块级和其他作用域

JavaScript1.7引入let关键词而带来了块级作用域的概念。

let定义的变量一旦执行点移出定义它的块就失效了。例如,我们常拥戴以下结构:

for (var i = 0; i < 10; i++) {
    //执行操作
}

alert(i);   //10

变量i在循环结束之后仍然可以访问。这里用了let而不是var,那么i在循环结束之后就不存在了。

for (let i = 0; i < 10; i++) {
    //执行操作
}

alert(i);    //错误!i未定义

还有其他使用let的方法。可以创建一个let语句特别定义在下一个代码块中使用的变量。

var num = 5;

let (num = 10, multiplier = 2) {
    alert(num * multiplier);    //20
}

alert(num);    //5

这段代码中,let语句定义了一个num变量为10且multiplier变量为2的区域。num的定义覆写了之前使用var进行声明的值,所以在let语句中两者相乘的结果是20;而在let语句之外,num的值仍然是5。由于每个let语句创建了它自己的作用域,内部的变量值不会影响到外部的变量值。

还可以使用类似的语法创建一个let表达式,其中变量值只针对单个表达式。如下例:

var result = let (num = 10, multiplier = 2) num * multiplier;
alert(result);    //20

这里,用了一个let表达式来使用两个变量计算一个值,然后该值被存储于result变量中。在这之后,变量num和multiplier不再存在。

生成器

生成器是一个可以依次产生一系列值的对象。在JavaScript1.7中,你可以通过定义一个函数使用yield操作符返回指定值来创建一个生成器。当调用使用了yield的函数,则创建并返回一个Generator实例。然后可以调用next()方法,检索生成器的第一个值。则中间会执行原来的函数一直到yield为止,并返回指定的值。其中yield的工作方式和return类似。如果再次调用了next(), 代码会继续从yield的下一个语句开始执行,然后继续运行到再次遇到yield为止,这时又返回一个新值。

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();
}

当调用myNumbers()函数时,返回一个生成器。myNumbers()函数本身简单,只包含一个for循环,每次循环都产生一个值。每次调用next()都会进行一次for循环,并返回下一个值。第一个值是0, 第二个为2, 第三个为4, 如此继续。当myNumbers()完成了,却没有用到yield(最后一次循环结束之后),调用next()会抛出一个StopIteration错误。所以要输出生成器所有的数字,while循环是包裹在try-catch语句中,以防止错误,而让嗲吗继续执行。

如果不需要某个生成器,最后调用close()方法。

当需要产生一系列值,并且每个后续的值都在某种程度上和前一个值相关,那么生成器就很有用了。

迭代起

迭代器提供了不使用循环而达到同样目的的能力。

要为某个对象创建迭代器,使用Iterator构造函数并传入要迭代内部值的对象。使用next()方法来检索序列中的下一个值。默认情况下,这个方法会返回一个数组,第一个元素是值的下标(对于数组)或属性名称(对于对象),第二个元素是对应的值。

var person = {
    name: "Nicholas",
    age: 29
};
var iterator = new Iterator(person);

try {
    while(true) {
        let value = iterator.next();
        document.write(value.join(":") + "<br />");
    }
} catch(ex) {
    //有目的留空
}

这段代码为person对象创建一个迭代器。第一次调用next()的时候,返回数组[“name”, “Nicholas”],第二次调用返回[“age”, 29].这段代码输出如下:

name: Nicholas
age: 29

为数组创建的迭代器

var colors = ["red", "green", "blue"];
var iterator = new Iterator(colors);

try {
    while (true) {
        let value = iterator.next();
        document.write(value.join(":") + "< br / >");
    }
} catch(ex) {

}

这段代码输出如下:

0:red
1:green
2:blue

可以通过给Iterator构造函数传递第二个参数,强制next()只返回属性名或者下标。如下:

var iterator = new Iterator(colors, true);

传递了第二个参数之后,每次调用next()将只返回值的索引而非包含索引和值的数组。

数组领悟

数组领悟是一种用满足特定条件的一些值初始化数组的方法。JavaScript中饿数组理解的基本形式如下:

array = [value for each (variable in values) condition ];

value是包含在最终数组中的实际值。这个值基于values数组中的所有值。foreach构成了迭代values中每个值的循环,并将值存在variable里。

//原始数组
var numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

//复制所有元素到数组
var duplicate = [i for each ( i in numbers)];

//只取出偶数
var evens = [i for each (i in numbers) if (i % 2 == 0)];

//每个值乘以2
var doubled = [i * 2 for each (i in numbers)];

//每个奇数乘以3
var tripledOdds = [i * 3 for each (i in numbers) if (i % 2 > 0)];

数组领悟的values布冯也可以是一个生成器或一个迭代器

解构赋值

var nextValue = ["color", "red"];
var name = nextValue[0];
var value = nextvalue[1];

解构赋值可以只用一个语句就将两个数组元素赋给变量。

var [name, value] = ["color", "red"];
alert(name);    //"color"
alert(value);    //"red"

如果不需要所有值,可以只为所需的值提供变量。

var [, value] = ["color", "red"];
alert(value);    //"red"

还可以创新的方式使用解构赋值,诸如交换两个变量的值。

var value1 = 5;
var value2 = 10;

var temp = value1;
value1 = value2;
value2 = temp;

使用解构赋值就可以消除临时变量

var value1 = 5;
var value2 = 10;

[value2, value1] = [value1, value2];

解构赋值也可以用于对象,也可以选择需要获取的值。

Loading Disqus comments...
Table of Contents