New in JavaScript 1.7

  JavaScript 1.7 介绍了一系列新的语言特性,特别是生成器、迭代器、数组领悟、let 表达式,以及解构赋值。它还引入了在JavaScript 1.6 中的全部特性。
  Firefox 2 Beta 1 开始提供对 JavaScript 1.7 的支持,当然也包括所有当前代码库(trunk目录)中的版本。
  本文中包含的代码示例可以在 JavaScript shell 中实验。请参照 Introduction to the JavaScript shell 来学习如何安装并使用 shell。 使用 JavaScript 1.7
  为了使用 JavaScript 1.7 的新特性,你需要指定 JavaScript 版本为 1.7。在HTML或者XUL代码中,这样写:
  当使用JavaScript shell 时,你需要通过在命令行添加-version 170 或者使用 version() 函数,来设置版本: version(170);
  如果用到了需要使用新关键字 "yield" 和 "let" 的特性,你就必须要指定版本为 1.7,因为已经写好的代码中可能会把那两个关键字当作变量名或者函数名来使用。如果没有涉及使用了新关键字的特性(解构赋值和数组领悟),就可以不指定 JavaScript 版本。 每当开发那些涉及到迭代算法(如对列表的迭代或对同一数据集进行相同的演算)的代码时,通常都需要声明一些变量,并在整个计算过程中都保留它们的值。一般来说,你还需要使用一个回调函数来获得迭代算法的中间值。 下面这个迭代算法计算了斐波那契数列: 这段代码使用了一个回调函数,来机械地执行算法每一步迭代的操作。这里,每一个斐波那契数都被简单地打印在控制台上。
  使用生成器和迭代器,可以提供一个更新更好的方法。现在就让我们来看看使用了生成器的斐波那契数列: 包含 yield 关键字的函数,就是一个生成器。当你调用它时,它的真正参数就会绑定到实际的变量上,但它自身其实并不做实际的计算,而是返回一个生成器-迭代器(generator-iterator)。每调用一次该生成器-迭代器的 next() 方法就再执行一次迭代算法。yield 关键字指定了每一步的值,就像生成器-迭代器版的 return 一样,指出了算法的每次迭代之间的边界。你每调用一次 next() ,生成器代码就从 yield 以下的语句处恢复。
  你可以重复调用一个生成器-迭代器的 next() 方法来使它转动,直到到达你期望的结果条件。在这个例子中,我们只需不停地调用 g.next() ,就可以获得任意多的斐波那契数,直到满足我们所需要的结果个数。 一个生成器在被调用其 next() 方法启动之后,你可以使用 send() 方法传递一个指定的的值,作为上一个 yield 的结果。这个生成器将返回后续 yield 的操作数。
  你无法强制生成器从某个位置启动,在你 send() 一个指定的值给生成器之前,你必须先以 next() 启动它。 注意: 有意思的是,调用 send(undefined) 与调用 next() 是等价的。不过,用任何除 undefined 之外的值调用 send() 启动一个刚刚创建的生成器将引发 TypeError 异常。
  生成器的异常
  通过调用生成器的 throw() 方法并传递异常值,你可以强制生成器抛出异常。此异常将从该生成器当前挂起的上下文中被抛出,就好像在当前被挂起的 yield 中插入了一个 throw value 语句。
  如果在抛出异常的过程中没有遇到 yield,那么该异常将被通过调用 throw() 传播,且后续的 next() 调用将导致 StopIteration 异常抛出。 关闭生成器
  生成器的 close() 方法能强行关闭生成器自身。关闭生成器的效果如下: 运行这个生成器函数中活动的 finally 语句。
  一旦 finally 语句抛出任何除 StopIteration 之外的异常,该异常被传播给 close() 方法的调用者。
  该生成器终结。
  生成器示例
  这段代码执行了一个每 100 次循环 yield 一次的生成器。 var gen = generator();
  function driveGenerator() {
  if (gen.next()) {
  window.setTimeout(driveGenerator, 0);
  } else {
  gen.close();
  }
  }
  function generator() {
  while (i 表达式 使你能在仅有一个表达式所限定的作用域内建立变量。
  let 定义 在一个块中,定义变量、常量和函数,并把它们的作用域限制在块内。从语法上看,let 定义 很类似 var 。
  你也可以使用 let 建立只存在于 for 循环上下文中的变量。
  let 语句为变量、常量和函数提供了本地作用域,其工作是把零个或多个变量绑定到单个代码块的词法作用域上,这个过程与块语句 完全相同。特别要注意的是,在 let 语句内部使用 var 声明的变量,其作用域和它在 let 语句外被声明时相同,这样的变量仍然具有函数作用域。
  例如: 这段程序的输出是: 此规则对任何 JavaScript 中的代码块适用。使用 let 声明,可以给代码块建立属于它自己的本地变量。 注意: 使用 let 语句这个语法时,跟在 let 后面的括号是必需的,丢掉它们将导致一个语法错误。
  作用域规则
  用 let 定义的变量的作用域是 let 块本身,覆盖了任何 let 块内部的块,除非这些内部块定义了同名的变量。 你可以使用 let 建立作用域仅在一个表达式中的变量。 输出如下: 在这个例子中,对 x 的值 x+10 的绑定和对 y 的值 12 的绑定的作用域被限制于表达式 x+y 。 let 关键字也可被用于在块中定义变量、常量和函数。 使用内部函数时,let 语句,let 表达式和 let 定义常常能使代码更加清晰。 上面的例子能像我们所期望的那样工作,因为五个匿名函数的实例引用了变量 j 的不同实例。请注意,如果你把 let 换成 var ,或者移除变量 j 并仅在内部函数中使用变量 i ,这段代码就不能正常工作了。 作用域规则
  用 let 定义的变量的作用域覆盖了它们被定义的块,已经任何没有重定义它们的子块。从这一点来看,let 的效果非常类似 var 。主要的区别在于用 var 定义的变量的作用域是整个闭合函数: function varTest() {
  var x = 31;
  if (true) {
  var x = 71; // 同一个变量!
  alert(x); // 71
  }
  alert(x); // 71
  }
  function letTest() {
  let x = 31;
  if (true) {
  let x = 71; // 不是一个变量
  alert(x); // 71
  }
  alert(x); // 31
  }
  = 右侧的表达式处于块的内部。这与 let -表达式和 let -语句的作用域不同: function letTests() {
  let x = 10;
  // let-语句
  let (x = x + 20) {
  alert(x); // 30
  }
  // let-表达式
  alert(let (x = x + 20) x); // 30
  // let-定义
  {
  let x = x + 20; // 这里的 x 的求值结果为 undefined
  alert(x); // undefined + 20 ==> NaN
  }
  }
  在程序和类中,let 不创建 global 对象上的属性,这与 var 的做法不同。但 let 会在一个隐含的块中创建属性,使其它上下文中的语句可以被求值。这就意味着,let 不会覆写前面用 var 定义的变量。例如: var x = 'global';
  let x = 42;
  document.write(this.x + "
\n");
  这段代码将输出 "global" 而不是 "42"。
  隐含的块 指的不是那种被括弧括起的块,它只由 JavaScript 引擎隐式创建。
  由 eval() 执行的 let 与 var 不同,它不会在变量对象(活动对象或在最内层绑定的组成部分)上创建属性。为使其它上下文中的语句可以被求值,它会在一个隐含的块中创建属性,这是 eval() 对于程序的操作与前述规则共同作用的结果。
  换句话说,当你使用 eval() 执行代码时,这段代码就被当作一段独立程序处理,拥有自己的包围其代码的隐含的块。 你可以使用 let 关键字在 for 循环的作用域内绑定本地变量,和使用 var 类似。 作用域规则
  for (let 表达式1 ; 表达式2 ; 表达式3 ) 语句
  在这个例子中,表达式1 ,表达式2 ,表达式3 和语句 都被闭合在一个隐含的块中,其中包含了用 let expr1 声明的本地变量。上面例子中的第一个循环示范了这个用法。 for (let 表达式1 in 表达式2 ) 语句
  for each(let 表达式1 in 表达式2 ) 语句
  在这两个例子中,都存在包含了每个 statement 的隐含的块。上面例子中的第二个循环展示了这里的第一种用法。 解构赋值使用了一种反映数组常量和对象常量结构的语法,使得从数组或对象中抽取数据成为可能。
  通过使用对象常量和数组常量表达式,你可以轻松地按需创建成包的数据,然后以任意你想要的方式使用它们。你甚至可以从函数中返回它们。
  而你使用解构赋值最重要的一件事就是,你可以从一个语句中读取整个结构。在这一节的余下的部分中会给出很多例子,你将看到你可以使用的很多有趣的功能。
  解构赋值这种能力与 Perl,Python 等语言所显示出的特性很类似。 用例子就可以很好地诠释解构赋值,所以这里几乎没有什么需要你通过阅读来学习的内容。 避免临时变量
  你可以用解构赋值来交换两个变量的值。例如: var a = 1;
  var b = 3;
  [a, b] = [b, a];
  这段代码执行之后,b 为 1,a 为 3。不使用解构赋值的话,这个工作就需要一个临时变量。(当然了,在某些低级语言中,可以使用 XOR-交换技巧 )
  与此类似,解构赋值也可以被用于三个或更多变量之间的轮换: var a = 'o';
  var b = "o";
  var c = 'o';
  var d = 'o';
  var e = 'o';
  var f = "o";
  var g = 'o';
  var h = 'o';
  for (lp=0;lp正则表达式匹配结果中倾倒值
  当正则表达式的 exec() 方法找到一个匹配时,它会返回一个数组,第一项是目标字符串中被匹配的完整部分,后面是被正则表达式中被括号括起的组所匹配的数段字符串。解构赋值使你能轻松地倾倒出该数组中的各个部分,并忽略掉其中不需要的匹配。 // 一个简单的正则表达式,用来匹配 http / https / ftp 型的 URL
  var parsedURL = /^(\w+)\:\/\/([^\/]+)\/(.*)$/.exec(url);
  if (!parsedURL)
  return null;
  var [, protocol, fullhost, fullpath] = parsedURL;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值