从代码示例了解ECMAScript5新特性

1. strict模式
strict模式目前无人实现,但是按标准的说法strict模式是非strict的完全子集

strict模式究竟是什么意思?很多同学认为使用strict模式是强迫使用良好的代码风格,我的意见是strict不是良好风格的代码而是高效的代码。通过使用strict模式,编译器有了把变量优化成内存地址的能力。

具体限制为
eval中不再能声明变量,声明的函数将会变成全局的
var定义只能在函数级,if、for、while、switch等不能有var定义
不能使用with语句
不能使用arguments.callee
普通的函数调用中this是null
试图改变只读属性将会抛出异常
delete失败会抛出异常
arguments不再和形参绑定 
函数不能有同名参数

使用的方法是用一个strict声明,这个声明是一个字符串表达式(为了兼容非strict模式),例如
strict声明只能是'use strict'和"use strict",包括转义、字符串断行在内的任何改动都不会被认为是strict声明
'use strict';
eval("var a=1;")
alert(a);
这里的strict声明导致代码全局变成strict模式,再无法使用非strict模式

strict也可以作用于函数级别, John Resig的建议很不错

 

// 非strict代码...
(function(){
  "use strict";  
  // 用strict模式编写我们的库
})();
// 用户仍然可以自由使用非strict代码...

 

 

 

2. 数组
数组变化不小,有一些用起来蛮顺手的扩展:
Array.prototype.indexOf, Array.prototype.lastIndexOf 正向查找和逆向查找,这个没什么好说的,看名字都知道是干什么的

Array的集合操作一直深得月同学喜爱,这下终于成了标准
Array.prototype.every:检查一个数组里所有元素都符合某个条件 数理逻辑中的任意符号 ∀(符号看不到的换宋体)

  1. <script>
  2. var arr = [2,9,4,5,3,7];
  3. var greater5 = arr.every(function(e,i){return e>5}); //是否大于5
  4. var smaller10 = arr.every(function(e,i){return e<10}); //是否小于10
  5. alert([greater5,smaller10]);
  6. </script>

Array.prototype.some : 检查一个数组里是否存在元素符合某个条件 数理逻辑中的存在符号 ∃

  1. <script>
  2. var arr = [2,9,4,5,3,7];
  3. var smaller5 = arr.some(function(e,i){return e<5}); //是否小于5
  4. var greater10 = arr.some(function(e,i){return e>10}); //是否大于10
  5. alert([smaller5 ,greater10]);
  6. </script>

Array.prototype.forEach : 这个就是普通的遍历了

Array.prototype.map : 对一个数组每一个元素执行函数,把所有返回值做为一个数组返回
  1. <script>
  2. var arr = [2,9,4,5,3,7];
  3. var smaller5 = arr.map(function(e,i){return e<5}); //是否小于5
  4. alert(smaller5);
  5. </script>

Array.prototype.filter : filter从一个数组中选出符合条件的元素,不过并不改变原来的数组
  1. <script>
  2. var arr = [2,9,4,5,3,7];
  3. var smaller5 = arr.filter(function(e,i){return e<5}); //是否小于5
  4. alert(smaller5);
  5. </script>

迭代操作
Array.prototype.reduce 和Array.prototype.reduceRight 提供了迭代操作
想想吧,用Array.prototype.forEach怎么求一个数组的所有元素的和?无论如何,你都需要用到一个外部变量。而Array.prototype.reduce更适合一些

  1. <script>
  2. var arr = [2,9,4,5,3,7];
  3. var sum = arr.reduce(function(sum,e,i){return sum+e;}); //是否小于5
  4. alert(sum);
  5. </script>

 

 3.Function.prototype.bind

对大多数JSer来说,Function.prototype.bind并不陌生了,这个prototype.js中的著名函数终于成为标准的一部分,并且有了更佳的内部实现方式。用法还是老样子
  1. <script>
  2. var f = function(){ return this.a + this.b}.bind({a:1,b:2});
  3. alert(f());
  4. </script>


4.String.prototype.trim
这个就是方便了,去掉字符串两端空格

alert("  啦啦  ".trim());


5. Date.now()是一个新的函数,得到当前的time stamp

这个是一个非常小的变动 实际相当于new Date().getTime()

  1. <script>
  2. alert([Date.now(),new Date().getTime()]);
  3. </script>

6.原型式编程 
Object.getPrototypeOf 可以获取一个对象的原型(注意,一个"对象"的原型,不是函数的prototype属性,即标准中所说的[[prototype]]) 这个函数的作用大致相当于SpiderMonkey的 __proto__属性,区别在于这个函数是低命名污染的,而且无法set

  1. <script>
  2. var klass = function() {}
  3. klass.prototype = {a:10};

  4. var obj = new klass();

  5. var proto= Object.getPrototypeOf(obj) 

  6. alert(proto == klass.prototype); 
  7. alert(proto.hasOwnProperty("a"));
  8. </script>


Object.create 可以以指定原型创建对象,效果大约等同于
function create(proto)
{
    var klass = function(){} ;
    klass.prototype = proto;
    return new klass;
}

Object.create的第二个参数是附加在新对象上的属性,可参考第三条

有意思的是,我们终于可以创建一个原型链“干净”的对象了,不需要每个对象都继承Object.prototype

代码
  1. <script>
  2. var obj=Object.create(null);
  3. alert(obj.toString);
  4. </script>




7.属性操作
Object.getOwnPropertyNames可以获取一个对象所有属性名组成的数组,包括那些不可枚举的属性,这是以前for in的替代品

  1. <script>
  2. alert(Object.getOwnPropertyNames(Object));
  3. </script>


Object.defineProperty是新的定义属性的方式,比起之前直接赋值,我们可以更好地控制属性的可访问性、可枚举性,大家一直期待的getter和setter也在此实现,正式成为标准:

一个只读属性的例子:
  1. <script>
  2. var obj = {a:1};
  3. Object.defineProperty(obj,"b",{value: 42, writable: false, configurable: true})
  4. alert(obj.b);
  5. obj.b = 10; // 无效
  6. alert(obj.b);
  7. </script>


一个getter和setter的例子
  1. <script>
  2. var a=10,b;
  3. var obj = {x:1};
  4. Object.defineProperty(obj,"c",{get:function(){return a+b}, set:function(v){b=v}});
  5. obj.c = 3;
  6. alert(obj.c);
  7. </script>


不能枚举的属性(以后扩展Array就不用心惊胆颤啦):
  1. <script>
  2. var obj = {a:1,c:3,d:4};
  3. Object.defineProperty(obj,"b",{value: 42, writable: false, configurable: true, enumrable:false});
  4. for(var p in obj)
  5. {
  6.     alert(p);
  7. }
  8. </script>


也可以用Object.getOwnPropertyDescriptor获取一个对象的属性的"属性"
  1. <script>
  2. alert(JSON.stringify(Object.getOwnPropertyDescriptor([],"length")));
  3. </script>


还支持一次定义好多属性Object.defineProperties 不过用处不大

8. JSON支持
JSON对象类似Math,其实就是命名空间的作用,实际只有2个函数JSON.stringify和JSON.parse

  1. <script>
  2. var jsonStr = JSON.stringify({a:10});
  3. alert(jsonStr);
  4. var obj = JSON.parse("{\"a\":10}");
  5. alert(obj.a);
  6. </script>


Date对象也添加了一个相关方法toJSON,像Date.now()一样,它也只是个快捷的东西

  1. <script>
  2. alert([JSON.stringify(new Date),(new Date).toJSON()]);
  3. </script>

 

posted @ 2012-02-28 13:30 winter-cn 阅读(...) 评论(...) 编辑 收藏