ECMAScript5 严格模式,JSON,及其它

ECMAScript5 规范自推出以来, 对javascript的发展产生了蛮大的影响。这篇文章是我翻译自John Resig(jQuery作者)的一篇博文  《ECMAScript 5 Strict Mode, JSON, and More》

----------

之前我分析了ES5的对象和属性系统。这是这门语言的一大亮点。

同样有许多其他新特性和API也需要我们注意。最主要的有严格模式(Strict Mode)和原生JSON支持(native JSON support)。

严格模式(Strict Mode)

严格模式在ES5中是个新特性,它允许你在一个“严格”的环境中执行你的代码。严格的环境会阻止采用一些特定的代码行为,抛出更多的异常(总体上说给用户更多的信息和规范编码)。

自ES5对ES3进行兼容后,所有在ES3中可以正常使用,但在ES5中注为“不推荐”的特性将在严格模式下失效(或者抛出异常)。

严格模式将以如下这些方式推进代码规范:

  • 捕获一些常见的代码漏洞,抛出异常

  • 当一些相对“不安全”的代码被执行时,进行阻止或抛出异常(例如获取全局对象访问)

  • 禁掉那些令人疑惑或者欠考虑的特性

大多数关于严格模式的信息可以在ES5规范[PDF]223页找到。

应该注意的是ES5的严格模式与FireFox提供的严格模式不同(可以通过about:config来启动javascript.options.strict)。ES5关注编码规范上的潜在错误。(而FireFox的严格模式只是强调一些最佳实践)。

如何启动严格模式?

很简单。在你的代码前加上"use strict",为你所有代码启动严格模式:

1
"use strict";

或者只在一个执行上下文内,如:

1
2
3
4
function imStrict() {
    "use strict";
    // ... your code...
}

看吧,启动严格模式的语法,不能再简单了,就一条语句"use strict"就行了。没有新的语法,不需要什么复杂的配置,并且对老的浏览器也没什么副作用。

ES5并没有对语言语法进行添加或者更改。所以可以在老浏览器中进行优雅降级。

在一个函数中定义严格模式,你可以在其中定义自己的javascript库,而不影响外部的代码。

1
2
3
4
5
6
7
// Non-strict code...
(function() {
    "use strict";
     
    // Define your library strictly...
})();
// Non-strict code...

当前很多库用上面的这种包裹技术(把整个库包在一个自动执行的匿名函数中)。

那么当你把脚本置于严格模式后,会发生什么呢?很多事情

变量和属性

尝试赋值foo = 'bar';如果'foo'没有事先定义,那么将失败。在这之前,foo会被赋值,并且foo会作为全局对象window的属性window.foo,现在这会抛出异常。确保避免一些恼人的bug。

对任何writable属性(attribute)为false的属性(property)进行写操作,configurable属性(attribute)为false的属性(property)进行删除操作,extensible属性(attribute)为false的对象进行添加属性(property)都会导致报错。传统上,当尝试这些行为时错误不会被抛出,将静静地失败。

删除变量,一个函数,一个参数将导致错误。

1
2
3
4
5
6
7
8
9
var foo = "test";
function test() {}
delete foo;   // Error
delete test;  // Error
function test2(arg) {
    delete arg;       // Error          
}

在一个字面对象中不止一次定义一个同名属性,将导致异常抛出

1
2
// Error
{ foo: true, foo: false }

eval

几乎任何尝试使用'eval'这个名称的操作都会被禁止.

1
2
3
4
5
6
7
8
9
// All generate errors...
obj.eval = ...
obj.foo = eval;
var eval = ...;
for(var eval in ...) {}
function eval() {}
function test(eval) {}
function(eval) {}
new Function("eval")

除此之外,通过eval引入的新变量无效

1
2
eval("var a = false;");
print(typeof a); // undefined

Functions

试图去覆写arguments对象将导致出错:

1
arguments = [...]; // now allowed

定义同名的参数会导致错误:function(foo, foo)

对arguments.caller和arguments.callee的访问将抛出异常。因此任何你想引用的匿名函数要给个名称,像这样:

1
2
3
4
setTimeout(function later() {
    // do stuff...
    setTimeout(later, 1000);
}, 1000);

其他函数的arguments和caller属性不在存在,并且定义它们的能力被禁止:

1
2
3
4
5
6
7
function test() {
    function inner() {
        // Don't exist, either
        test.arguments = ...; // Error
        inner.caller = ...; // Error
    }
}

最后一个长期困扰的(并且很恼人的)bug被解决了:像如下用例中,null或者undefined被强制转换为全局对象。严格模式现在阻止这样的事情发生,并会抛个异常。

1
(function() { ... }).call(null); // Exception

with

with语句在严格模式中完全被干掉了,事实上它的出现会作为语法错误。

ES5严格模式对代码的改变是多样的。观察开发者如何开始采用这些规范和它如何改变javascript开发,将是个有趣的过程。

JSON

ECMAScript语言第二个主要的特性是加入了对JSON的原生支持。

我已经拥护此项推进很久了,如今我很高兴的看到它被写入了规范。

有2个主要的方法用于处理JSON:JSON.parse(把一个JSON字符串转成一个javascript对象)和JSON.stringify(把一个javascript对象转成一个序列化的字符串)。

JSON.parse(text)

把一个序列化的JSON字符串转成一个javascript对象。

1
2
3
var obj = JSON.parse('{"name": "John"}');
// Prints 'John'
print(obj.name);

JSON.parse(text, translate)

使用一个转换函数 转换值或者进行移除

1
2
3
4
5
6
7
8
9
10
11
12
function translate(key, value) {
    if( key === "name") {
        return value + " Resig";
    }
}
var obj = JSON.parse('{"name": "John", "last": "Resig"}', translate);
// Prints 'John Resig'
print( obj.name );
// Undefined
print( obj.last );

JSON.stringify(obj)

把一个对象转成一个序列化的JSON字符串

1
2
3
var str = JSON.stringify({name: "John"});
// Prints {"name": "John"}
print( str );

JSON.stringify(obj, ["white", "list"])

只序列化白名单指定的属性

1
2
3
4
var list = ["name"];
var str = JSON.stringify({name: "John", last: "Resig"}, list);
// Prints {"name": "John"}
print( str );

JSON.stringify(obj, translate)

用转换函数来序列化对象

1
2
3
4
5
6
7
8
9
function translate(key, value) {
    if(key === "name") {
        return value + " Resig";
    }
}
var str = JSON.stringify({"name""John""last""Resig"}, translate);
// Prints {"name": "John Resig"}
print( str );

JSON.stringify(obj, null, 2)

给输出增加指定的空格数

1
2
3
4
5
6
var str = JSON.stringify({ name: "John" }, null, 2);
// prints
// {
//   "name": "John"
// }
print( str );

JSON.stringify(obj, null, "\t")

使用特定的字符来做分隔

1
2
3
4
var str = JSON.stringify({ name: "John" }, null"\t");
// Prints:
// {\n\t"name": "John"\n}
print( str );

另外,一些基础类型添加了新的通用方法,但是,恕我直言,它们并不有趣。来自String,Boolean和Number的结果等同于调用valueOf(), Date的结果等同于调用toISOString()

1
2
3
4
5
// Yawn
String.prototype.toJSON
Boolean.prototype.toJSON
Number.prototype.toJSON
Date.prototype.toJSON

.bind()

内置bind()方法的引入很受欢迎,它可以使一个函数的执行环境得到改变(几乎等同于prototype framework中的bind实现)

1
Function.prototype.bind(thisArg, arg1, arg2...)

使得函数的this关键字指向一个特定的对象,并传入任何你要指定的参数。

1
2
3
4
5
6
7
var obj = {
    method: function(name) {
        this.name = name;
    }
};
setTimeout(obj.method.bind(obj, "John"), 100);

Date

首先,如果所给的值是ISO格式,Date构造函数会试图去解析该日期,接着再处理它接受的其他输入。

1
2
3
4
var date = new Date("2009-05-21T16:06:05.000Z");
// Prints 2009-05-21T16:06:05.000Z
print( date.toISOString() );

另外,date对象现在有个新的toISOString()方法,以ISO格式输出日期

.trim()

一个原生,内置的trim()方法被String对象支持,和我们自己实现的trim方法功能一样,但是原生的效率更高。

Array

JavaScript Array扩展方法包括: indexOf, lastIndexOf, every, some, forEach, map, filter, reduce 和 reduceRight

另外一个新方法Array.isArray(译者注:可以理解为Array的static方法)被包含了进来, 提供和下面这段代码同样地功能:

1
2
3
Array.isArray = function( array ) {
    return Object.prototype.toString.call( array ) === "[object Array]";
}

ECMAScript5 严格模式,JSON,及其它相关推荐

  1. python之ddt模式json随记

    ddt数据驱动模式还可以使用json文件来作为数据驱动,如下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import ddt import unittest ## ...

  2. BC26通过LWM2M接入电信AEP平台(非透传模式 Json格式)

    透传模式接入可以看 https://blog.csdn.net/qlexcel/article/details/117217287 LWM2M协议简介   LwM2M(lightweight Mach ...

  3. 深圳软件测试培训:Json解析

    深圳软件测试培训:Json解析 JSON是JavaScript的一个严格的子集,利用JavaScript中的一些模式来表示结构化数据. 一.JSON语法 JSON和XML类型,都是一种结构化的数据表示 ...

  4. ActiveReports 报表控件V12新特性 -- 新增JSON和CSV导出

    ActiveReports 报表控件V12新特性 -- 新增JSON和CSV导出 ActiveReports 是一款专注于 .NET 平台的报表控件,全面满足 HTML5 / WinForms / A ...

  5. 深入理解JSON对象

    深入理解JSON对象 前面的话 json(javascript object notation)全称是javascript对象表示法,它是一种数据交换的文本格式,而不是一种编程语言,用于读取结构化数据 ...

  6. 对JavaScript解析JSON格式数据的理解

    对JavaScript解析JSON格式数据的理解 一.JSON与JavaScript对象的关系 1,JSON的由来: 在21世纪初,Douglas Crockford(Web开发领域最知名的技术权威之 ...

  7. javaScript系列 [05]-javaScript和JSON

    本文输出和JSON有关的以下内容 JSON和javaScript JSON的语法介绍 JSON的数据类型 JSON和XMLHTTPRequest JSON的序列化和反序列化处理 1.1 JSON和ja ...

  8. JavaScript:JSON详解

    向服务器发出Ajax请求时,可以以两种不同的方式从服务器响应检索数据:一种是使用XMLHttpRequest对象的reponseXML属性访问XML格式的数据:一种是XMLHttpRequest对象的 ...

  9. 网站的护眼模式和夜间模式

    网站的护眼模式和夜间模式 不采用数据库存储字段的方式,而采用cookie来判断是哪种模式 如果会使用js对cookie进行赋值,取值,删除,也可以只用js做 护眼模式图示: 1 给按钮绑定事件 < ...

最新文章

  1. ISA Server中基于L2TP实现远程拨入***
  2. BurpSuite 代理设置的小技巧
  3. 体验XHProf(linux版本)
  4. php 返回页面重复提交,php防止表单重复提交
  5. 下载anaconda时出现“Please make sure you are connected to the internet”警告
  6. 第一阶段:前端开发_Mysql——表与表之间的关系
  7. 从无头单链表中删除节点
  8. cuSPARSE库:(十二)cusparseDestroyMatDescr()
  9. ASP.NET MVC 2 正式版发布了的
  10. linux解压缩6层
  11. java经典算法(一)——zws
  12. HTML制作简单的页面
  13. 系统论、控制论和信息论
  14. android气泡样式图片,Android实现三角形气泡效果方式汇总
  15. 达梦redo log损坏的处理办法
  16. Git工作模式_繁星漫天_新浪博客
  17. 振兴当当,李国庆如何逐鹿中原?
  18. 针对尚硅谷教学微服务硅谷课堂在线学习平台的部分功能的自我改进
  19. React - Content
  20. 新文速递 | 数商:数据商品、数据商人和数据商业

热门文章

  1. JavaScript30秒, 从入门到放弃之Array(三)
  2. JavaScript 进阶(二)变量作用域
  3. IOS 实现TXT文本自动识别编码的方法
  4. Neutron 如何支持多种 network provider - 每天5分钟玩转 OpenStack(70)
  5. CGRectInset CGRectoffset UIEdgeInsetsInsetRect 这三个函数的使用情况
  6. Thinkpad X240使用U盘安装Win7系统
  7. 管理用户和PROFILE——用户方案和profile
  8. tolua++ 手册翻译地址
  9. JAVA中string的赋值_Java中关于String赋值的两种形式
  10. python里的join方法_python中join()方法介绍