`
无尘道长
  • 浏览: 157771 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JavaScript编码规范

阅读更多

 博文说明:该博文是从我之前写的JavaScript编码规范文档中copy出来,copy后,文本样式有所变化,可直接下载word的附件。

 

 

 

 

 

 

JavaScript编码规范

 

 

 

 

201111

 

 

                                规范基本信息表:

 

规范简称:

JavaScript编码规范

规范版本号:

1.0

规范修订日期:

2011-12-15

本规范位置:

 

先前版本位置:

 

规范制定组织:

 

规范制定牵头人:

王能

规范校订人:

 

 

JavaScript编码规范

 1 概要

 1.1 规范摘要

    本规范主要目的是定义基于JavaScript编码的总体规范,确保编码的规范性,提高程序的可维护性。通过遵循共同的编码规范,程序开发人员可以保持代码一贯的风格,提高代码编写的可读性和使用的一贯性。

 1.2 背景

 1.3 现状

 1.4 相关工作说明

 1.5 规范声明

2 适用范围

3 引言

3.1 词汇表

3.1.1 首选术语

3.1.2 相关术语

3.2 格式约定

3.3 文件引用

 《ECMAScript-262标准》。

 《JavaScript权威指南V5》。

 《JavaScript高级程序设计V2》。

 《JavaScript高性能》。

 《Google JavaScript开发规范》。

4 需求

5 规范正文

5.1 排版规范

5.1.1 文件结构

 

JavaScript文件按如下顺序组织各元素:

 

序号

元素

说明

1

版权、版本声明

以注释的方式进行声明

2

总体注释

在注释中总体介绍该文件实现的功能;

对如何使用这些功能给出指导性意见;

给出使用示例;

指出注意事项;

罗列依赖的其它JavaScript文件;

注明:第一作者、第二作者

3

程序内容

 

 

5.1.2 缩进排版

 

4个空格为一个缩进单元,避免使用Tab制表符。

 

【示例】:

 

function getUser(id) {

if ( !id ) {

    throw new Error(“”);

}

}

 

5.1.3 行排版

 

一行的字符不建议超过120个字符,一行过多的字符会影响查看程序的效率。

 

如果一段描述不能放在一行中,依据下列规则将其拆分成多行:

 1)       从分隔符(比如空格)后换行;

 2)       在运算符之前换行;

 3)        不拆分完整的单词;

 4)        换行后如果需要缩进则不应缩进超过行中。

 

【示例】:

 

if ((condition1 && condition2) || (condition3 && condition4)

||!(condition5 && condition6)) {

}

 

5.1.4 空白的使用

 

函数之间空1行,get/set方法除外。

 

【示例】:

 

function createUser() {

}

 

function destoryUser() {

}

 

function getUser() {

    return this.user;

}

function setUser(user) {

    this.user = user;

}

 

 

 

代码逻辑段之间空一行。

 

【示例】:

 

function getUser(id) {

//判断参数id的合法性

if ( !id ) {

    throw new Error(“”);

}

 

//根据参数id查找user对象

findUser(id);

}

 

5.1.5 语句

5.1.5.1 表达式语句

 

表达式语句以分号结束

 

【示例】:

 

var i = 0;

alert(提示信息);

Math.cos(x);

 

5.1.5.2 复合语句

 复合语句是包含在花括号中的一个语句或者语句块,复合语句遵循如下排版规则:

 1)      左花括号”{” 位于复合语句起始行的行尾, 右大括号"}"应另起一行并与复合语句首行对齐;

 2)      花括号中的语句缩进一个层次(4个空格)。返回语句

 

【示例】:

 

{

    var x = 0;

}

 

5.1.5.3 if-else语句

 

 if-else语句总是用"{""}"括起来,避免发生错误。

 

【示例】:

 

if ( expression1 ) {

statement1;

} else if ( expression2 ) {

statement2;

} else {

    statement3;

}

 

5.1.5.4 for语句

 

【示例】:

 

for (initialize; test; increment) {

statement;

}

 

一个空的for语句:在初始化,条件判断,更新子句中完成,应该具有如下格式:

 

【示例】:

 

for (initialize; test; increment);

 

5.1.5.5 for-in语句

 

【示例】:

 

for ( variable in object ) {

statement;

}

 

5.1.5.6 while语句

 

【示例】:

 

while ( expression ) {

statement;

}

 

5.1.5.7 do-while语句

 

【示例】:

 

do {

statement;

} while ( expression );

 

5.1.5.8 switch语句

 

【示例】:

 

switch ( expression ) {

case value1:

statement;

break;

case value2:

statement;

break;

default:

statement;

break;

}

 

当一个执行完一个case后需要顺着往下执行(即没有break语句)时,通常应在break语句的位置添加注释。上面的示例代码中就包含注释/* */

 

5.1.5.9 try-catch-finally语句

 

【示例】:

 

try {

statement;

} catch ( e ) {

statement;

} finally {

    statement;

}

 

5.2 注释规范

5.2.1 注释位置

 1)   函数和方法:每个函数和方法都应该包含一个注释,描述其目的和用于完成任务所可能使用的算法,基于参数类型、参数可选择值、返回值;

 2)   大段代码:用于完成单个任务的多行代码应该在前面填加描述任务的注释;

 3)  复杂的算法:在使用复杂算法的代码处添加注释,以便下次查阅代码时帮助理解;

 4)   Hack:因为不同的浏览器存在差异,JavaScript以便会包含一些hack,需要在这些hack的代码前添加注释,以便提醒代码维护者。

5.2.2 块注释

 

块注释以/**开头或者/*开头,以 */结尾, Doc注释以/**开头,比如:注释在JavaScript文件开头、函数、变量上的注释通常会用于生成doc文档;非Doc注释的多行注释以/*开头。

 

Doc注释中需要注明类型,常见的类型包括:ObjectArrayFunctionNumberStringBooleanMath等,类型注释规则如下表:

 

符号

举例

说明

{类型}

{Object}

对象类型

{ | }

{Number | Object}

Number或者Object类型

{ ! }

{!Object}

非对象类型

{ ? }

 

未知类型

{ * }

 

所有类型

 

注:在注释中的Number包装类型代指Number类型或者number基本类型,其它包装类型类似。

 

Doc注释举例:

 

【示例】:

 

/**

 * {Object} 用户对象

*/

var user = {};

 

/**

 * 通过用户对象获取用户名称

 * @param {Object} user 用户对象

 * @return {String} 用户名称

 */

function getUserName(user) {

/*

     * 如果usernull,则该方法会出现异常,需要对输入参数user进行可靠性校验

     * 需判断user变量是否是user对象

*/

return user.name;

}

 

 

//如果没有返回值,可以不用在注释中写@return

/**

 * 设置用户名称

 * @param {Number} age 用户名称

*/

function setUserName(name) {

    this.name = name;

}

 

5.2.3 单行注释

 

单行注释,以//开头,非Doc注释时使用。

 

【示例】:

 

function getUserName(user) {

//返回用户名称

return user.name;

}

 

5.2.4 JavaScript文件注释

 

在文件头位置对JavaScript文件进行注释,说明该文件的版权、版本等信息

 

【示例】:

 

/**

 * 本文件是$项目名称 V$VERSION的一部分

 * Copyright (C) 2000-2011 公司名称

* Provider: 组织名称

* 联系方式:http://www.xxx.com/contact

* 版权说明:

 */

 

 

5.2.5 函数/方法注释

 

【示例】:

 

/**

 * 通过用户对象获取用户名称

 * @param {Object} user 用户对象

 * @return {String} 用户名称

 */

function getUserName(user) {

return user.name;

}

 

5.2.6 变量/属性注释

 

【示例】:

 

/**

 * {Object} 用户对象

*/

var user = {};

 

 

5.3 声明规范

 5.3.1 变量

 

局部变量和全局变量均使用var关键字进行声明。

 

【示例】:

 

var name = “”;

 

 

 

在同一作用域(在JavaScript中共三种作用域:全局作用域、局部作用域、嵌套局部作用域)的开头位置声明变量,避免出现重复声明变量的问题,forfor-in语句的循环变量除外。

 

【示例】:

 

//全局变量

var globalV = “global”;

 

function printUserProperty () {

//局部变量

var users = [{name:”用户1”}, {name:”用户2”}];

 

//for语句变量i, user

for( var i = 0, user; user = users[i]; i++ ) {

    printUserProperty(user);

}

 

function printUserProperty(user) {   

//嵌套局部变量

var count = 10;

 

//for-in语句变量prop

for ( var prop in user ) {

            alert(prop);

}

}

 

}

 

 

声明全局变量、对象属性、函数参数时需注释变量类型或者赋初值(通过初值确定变量类型),由于局部变量是在代码块内部定义,作用范围有限,因此不做要求。

 

【示例】:

 

//全局变量

var isSuccess = false;      //推荐的布尔类型初始值:false

var count = -1;             //推荐的number类型初始值:-1

var name = “”;            //推荐的字符串类型初始值:“”

var user = null;            //推荐的对象类型初始值:null

 

var obj = {

    //对象属性

name = “”

};

 

//函数参数

/**

* 设置名称

* @param {string} name 名称

* @return

*/

function setName(name) {

 

}

 

可以一次声明多个变量,变量之间用“,”分隔,如果变量有初值或者注释则需换行,换行后与上一行的第一个变量左对齐。

 

【示例】:

 

var name, password, age, sex;

 

//有注释或者初值应换行

var name, password,

age, //年龄

sex = “”;

 

采用直接量的方式声明对象,提高对象声明的代码可读性,对象属性和方法行前空4,对象的属性或者方法以“,”分隔,最后一个属性或者方法不应出现“,”, 属性之间不空行,方法之间空两行。

 

【示例】:

 

//

var user = {

id:””,

name:“”,

 

setName: function(name) {

    this.name = name;

},

 

getName: function() {

    return this.name;

}

 

}

 

//

var user = new Object();

user.id = “”;

user.name = “”;

user.setName = function(name) {

    this.name = name;

}

user.getName = function() {

    return this.name;

}

 

采用直接量的方式声明数组,尽量不采用构造函数,避免错误。

 

【示例】:

 

//

var arr = [x1];

 

//

//如果x1是正整数,则数组长度=x1

//如果x1是非正整数的number,则会出现error

//如果x1是非number类型,数组长度=1,x1将作为数组的一个内容

var arr = new Array(x1);

 

5.3.2 函数

 

使用function关键字声明函数。

 

【示例】:

 

function getUser() {

}

 

//函数变量

var getUser = function() {

}

 

函数参数之间用“,”分隔。

 

【示例】:

 

function createUser(id, name, password) {

}

 

函数代码行前空4格。

 

【示例】:

 

function getUser() {

    return {name:”用户”};

}

 

相邻函数之间空2

 

【示例】:

 

function setUser() {

}

 

function setUser(user) {

}

 

匿名函数的右花括号右端不应有代码,左花括号左端不应有代码。

 

【示例】:

 

excute('whatever', function(p1, p2) {

   

});

 

<script>function的根下声明函数,避免在if等语句块下声明函数,以符合ECMAScript-262标准。

 

【示例】:

 

//劣:

if (x) {

function foo() {}

}

 

//替代方案:使用函数变量

if (x) {

var foo = function() {}

}

 

5.4 命名规范

5.4.1 文件

 

当在一个project中引入其它JavaScript文件时,会存在文件名称相同的可能,因此需要采取一定的措施减少重名的可能性,推荐的方式:<公司名称>.<项目名称>.<模块名称> [.<子模块名称>[]].js,文件名称全部小写。

 

【示例】:

 

epri.sotower.ui.grid.js

 

5.4.2 命名空间

 

JavaScript中,通过对象的属性模拟命名空间,避免变量、函数重名,推荐的命名规则与文件命名基本一致。

 

【示例】:

 

//epri.sotower.ui.grid.js文件中为Grid对象定义一个方法createGrid

var epri= epri|| {};

if ( typeof(epri) != object ) {

    throw new Error(命名空间epri已经存在但是不是对象!);

}

 

epri.sotower = epri.sotower || {};

if ( typeof(epri.sotower) != object ) {

    throw new Error(命名空间epri.sotower已经存在但是不是对象!);

}

 

epri.sotower.ui = epri.sotower.ui || {};

if ( typeof(epri.sotower.ui) != object ) {

    throw new Error(命名空间epri.sotower.ui已经存在但是不是对象!);

}

 

if (epri.sotower.ui.Grid  ) {

    throw new Error(epri.sotower.ui.Grid已经存在!);

}

 

sotower.ui.Grid = {

createGrid: function() {

}

};

 

//执行Grid类的createGrid方法

epri.sotower.ui.Grid.createGrid();

 

5.4.3 构造函数/

 

构造函数是指:初始化一个对象的属性并且专门和new运算符一起使用的函数,通常采用构造函数实现类的概念,构造函数采用首字母大写的驼峰式命名。

 

【示例】:

 

function User(id, name, password) {

this.id = id;

this.name = name;

this.password = password;

}

 

var user = new User(id1, 用户, 111111);

alert(user.name);

 

5.4.4 变量/对象属性

 

在本小节变量代指:变量/对象属性。

 

变量由字母、数字或下划线组成,变量的第一个字符不能是数字,变量的名称不能是JavaScript保留字(参考附录1)。

 

【示例】:

 

//正确

var user = null;

var _user = null;

var _user1 = null;

 

//错误

var 1user = null;

var $user = null;

 

变量采用首字母小写的驼峰式命名。

 

【示例】:

 

var userName = “”;

 

var user = {

    userName:””

};

 

变量名称应具有一定的含义。

 

【示例】:

 

//

var userName = “”;

 

//

var aa = “”;

 

JavaScript中没有私有变量的语法,但是可以通过注释或者为变量增加_前缀等方式表示为私有变量,通常采用加_前缀的方式。

 

【示例】:

 

var user = {

//私有变量

_roles:[],

 

 

getRoles: function() {

    return this._roles;

}

}

 

5.4.5 常量

 

JavaScript中没有常量的语法,但是可以采取特殊的命名方式把一个变量表示为常量:所有字母大写,单词之间用“_“链接。

 

【示例】:

 

var MAX_WIDTH = 1024;

 

5.4.6 函数/对象方法

 

对象方法是作为对象属性的函数,因此在本小节中函数代指:函数/对象方法。

 

函数名称由字母、数字或下划线组成,第一个字符不能是数字,函数名称不能是JavaScript保留字(参考附录1)。

 

【示例】:

 

//正确

function getUser() {

}

function _getUser2() {

}

 

//错误

function 1getUser() {

}

function get&User() {

}

 

函数名称采用首字母小写的驼峰式命名。

 

【示例】:

 

function getUser() {

}

 

函数名称应具有一定的含义。

 

【示例】:

 

//

function getUser() {

}

 

//

function aa() {

}

 

函数名称通常以动词开头

 

【示例】:

 

//

function getUser() {

}

 

//

function user() {

}

 

变量/对象属性对应的存值、取值方法分别通过setget命名,如果变量/对象属性是boolean类型,则建议可以使用is替代get,替换后的方法更易理解。

 

【示例】:

 

var user = {

name:””,

sex:,

 

getName: function() {

    return this.name;

},

 

setName: function(name) {

    this.name = name;

},

 

isBoy: function() {

    return this.sex == ;

}

};

 

5.4.7 事件

 

处理事件的函数名称以“Handler“后缀结尾,在名称中需要包含事件的类型和代表触发事件的HTML元素的名称。

 

【示例】:

 

//在页面中有一个输入用户名称的input框,则处理它的onchange事件的函数命名如下:

function userNameInputChangeHandler(e) {

}

 

5.5 编码健壮性遵循原则

 5.5.1 合理使用闭包

 

闭包容易导致内存泄露,尤其是使用闭包函数处理DOM事件时经常会出现HTML元素与闭包函数的相互引用,从而导致无法释放HTML元素和闭包函数的内存。

 

【示例】:

 

//

//在执行完foo方法后,局部变量element不会被垃圾回收,因为它的闭包函数被注册到element元素的单击//事件中,被element引用,而闭包函数又持有foo函数内的所有变量包括element,如此形成elementfoo

//内的闭包函数的循环引用,从而elementfoo均不能被垃圾回收,导致内存泄露。

function foo(element, a, b) {

element.onclick = function() {

/* 使用变量ab */

};

}

 

//

//改造后的正确用法如下:

// element会引用函数bar返回的函数,不会引用到foo, 避免了循环引用,从而执行完foo方法后,element

//将被垃圾回收。

function foo(element, a, b) {

element.onclick = bar(a, b);

}

 

function bar(a, b) {

return function() {

/* 使用ab */

}

}

 

5.5.2 合理使用forfor-in循环

 

使用普通的for语句循环数组,使用for-in语句循环对象,不建议使用for-in语句循环数组,因为如果使用for-in循环数组在一些使用场景下会导致问题。

 

【示例】:

 

//

function printArray(arr) {

for (var key in arr) {

        alert(arr[key]);

    }

}

 

printArray([0,1,2,3]);  // 可以alert出正确的结果

 

var a = new Array(10);

printArray(a);         // 错误:没有alert

 

a = document.getElementsByTagName('*');

printArray(a);        // 错误:会alertalength

 

a = [0,1,2,3];

a.buhu = 'wine';

printArray(a);       // 错误:会alertwine

 

a = new Array;

a[3] = 3;

printArray(a);       // 错误:只alert一次

 

//

//把以上示例的for-in语句改造成普通的for语句,则不存在以上问题

function printArray(arr) {

    var l = arr.length;

    for (var i = 0; i < l; i++) {

        alert(arr[i]);

    }

}

 

只在循环对象时使用for-in

 

【示例】:

 

for ( var p in user ) {

alert(p);

}

//注意添加到对象的prototype中的成员将被包含在遍历中,可以通过使用hasOwnProperty方法来区分是否对象自有属性或者方法。

 

5.5.3 避免无限循环

 1)   在使用for等循环语句进行循环时,要确保终止循环的条件一定能被触发,避免无限循环;

 2)   避免函数之间相互调用,形成隐式无限循环。

 

【示例】:

 

//错误

function f1() {

f2();

}

 

function f2() {

f1();

}

 

f1();

 

5.5.4 区分=====

 

===是完全等于,即除了值必须相等外,类型也必须相等。

 

【示例】:

 

var v1 = 1;

var v2 = 1;

alert(v1 == v2); //true

alert( v1 === v2 );//false

 

5.5.5 字符串拼接

 

使用“+”进行字符串多行拼接,不建议使用“\”,因为MCMAScript标准不支持“\”拼接方式,并且“\”拼接方式会导致行前的空白被包含在变量中。

 

【示例】:

 

//

var myString = 'A rather long string of English text, an error message \

            actually that just keeps going and going -- an error \

            just gravy.  Have a nice day.';

 

//

var myString = 'A rather long string of English text, an error message ' +

 'actually that just keeps going and going -- an error ' +

    'just gravy.  Have a nice day.';

 

5.5.6 避免在函数中定义全局变量

 

【示例】:

 

//

function doSomething() {

    user = {};   //不使用var关键字会定义一个全局的user变量

}

 

5.5.7 避免在JavaScript中包含过多的HTMLCSS内容

 

JavaScript中尽量少包含CSS样式、HTML的内容,如果必须使用CSS,尽量把样式写入CSS文件,在JavaScript中对class进行操作,如果必须使用HTML,且HTML内容比较多,则应该把HTML相关内容归集到一个文件中,并根据需要使用模板技术。

 

5.5.8 异常处理

 1)   把可能出现错误的程序块放入try语句中,把处理错误的代码放到catch或者finally语句中;

 2)   ECMAScript只为Error对象定义了两个属性,一个是保存错误信息的message属性,一个是保存错误类型的name属性(ECMAScript共定义了7中错误类型,其中Error是基本错误类型),但是IE、FireFox等浏览器通常会为Error添加自有的属性,因此如果应用需要支持跨浏览器,只使用message、name属性。

 3)  在finally子句中使用return语句时,return的应该是一个变量。

 

【示例】:

 

//

try {

return 2;

} catch( e ) {

   

} finally {

return 1;   //最终返回的永远是1

}

 

//

var rv = -1;

try {

rv = 2;

} catch( e ) {

rv = 1;

} finally {

return rv;   //如果没有错误则返回2,有错误则返回1

}

 4)   使用throw关键字抛出异常,throw的应该是Error或者Error的子对象。

 

                                                                           【示例】:

 

//

throw “”;

 

//

throw new Error(msg);  //new一个Error或者Error的子对象

 5)   在可以的情况下,尽量使用throw抛出自己的异常信息,避免出现错误时,显示的是浏览器默认的错误信息,不利于排错,尤其是生产环境下,有较好的自定义错误信息,将对排错提供很好的帮助。

 

【示例】:

 

//

function process(values) {

if ( !values ) {

throw new Error(xx.js  process(): 参数values 必须有值”);

}

}

 6)   只处理可以处理的错误;

 7)   通过原型prototype继承Error类,实现自定义错误类型。

 

【示例】:

 

function  SelfError(message) {

this.name = SelfError;

this.message = message;

}

 

SelfError.prototype = new Error();

 8)   记录JavaScript错误到服务器端,以便分析错误。

 

【示例】:

 

/**

* 通过Image元素记录错误到服务器端

* @param {String} level 错误级别,可选值:debuginfowarnerorr

* @param {String} msg 错误信息

*/

function logError(level, msg) {

var img = new Image();

img.src = /context/log.so?level= + encodeURIComponent(level)  + &msg= +

         encodeURLComponent(msg);

}

 

for ( var i = 0; i < 100; i++ ) {

try {

//Code

} catch ( error ) {

logError(info, “处理…时发生错误,错误时的状态是…”);

}

}

 

5.6 性能优化

 5.6.1 合理使用prototype

 

在使用prototype实现继承时,不应层级太多,否则会影响到在子类中使用父类方法时的性能。

 5.6.2 本地缓存对象属性

 

在多次使用对象属性的程序块中,应该为属性定义本地变量,在后续程序只使用本地变量,这样可以减少JavaScript引擎在对象中查找属性的次数,提高访问性能,在循环中使用引用时尤其有效。

 

【示例】:

 

var obj = {name:’’};

 

var name = obj.name;

var obj2 = {};

for ( var i = 0; i < 100; i++ ) {

obj2.name = name + i;

}

 5.6.3 减少操作HTML DOM结构的次数

 

尽量减少JavaScript操作DOM的次数,在对DOM进行新增、替换节点时,可以先把相应的内容准备好后,通过innerHTML方式一次完成对DOM的操作。

 

5.6.4 减少在HTML中嵌入过多JavaScript代码

 

尽量减少在HTML文件中嵌入的JavaScript代码,把JavaScript代码归集到JavaScript文件中,可以借助JavaScript编译工具进行优化和压缩,从而减小网络流量。

 

5.6.5 引用JavaScript文件

 

<script src=filename.js>标签可以放在body的最后,以便减少由于加载script文件而导致其它页面组件的延迟显示的问题。

 

5.6.6 压缩JavaScript文件

 

使用Google Compiler压缩JavaScript文件,在项目中只使用压缩后的JavaScript文件,提高JavaScript文件加载速度。

 

5.6.7 事件代理

 

在为HTML添加较多事件函数时,建议采用事件代理机制,在父节点代理所有子节点进行事件处理,避免浏览器为子节点注册事件,在子节点比较多时,比如:为表格的每个单元格注册事件处理器时采用机制代理机制对性能改善尤为明显。

 

6 一致性约束

 

6.1 引言

 

本文档主要是规范实现过程中的编码实现,以保证JavaScript编码的统一,增加可读性、可维护性。

 

6.2 一致性考查表

 

此表用于描述在前述规范中提到的各项规范的约束等级,分为强制和推荐两级。任何强制性约束没有满足时,处于未遵守此规范的状况;满足所有强制性约束,但未实现部分或全部推荐性约束时,处于遵守此规范的状况;全部实现所有强制性和推荐性约束时,处于完全符合此规范的状况

 

规范点标记

规范点说明

约束等级(强制:M,推荐:O

5.1

排版规范

M

5.2

注释

M

5.3

声明规范

M

5.4

命名规范

M

5.5

编码健壮性遵循原则

M

5.6

性能优化

M

5.6.1

合理使用prototype

O

5.6.2

本地缓存对象属性

O

5.6.3

减少操作HTML DOM结构的次数

M

5.6.4

减少在HTML中嵌入过多JavaScript代码

O

5.6.5

引用JavaScript文件

O

5.6.6

压缩JavaScript文件

M

5.6.7

事件代理

O

 

7 附录

 

7.1 保留字

 

正在使用的保留字

 

break

delete

function

return

typeof

case

do

if

switch

var

catch

else

in

this

void

continue

false

instanceof

throw

while

debugger

finally

new

true

with

default

for

null

try

 

 

 

 

为将来保留的字

 

abstract

double

goto

native

static

boolean

enum

implements

package

super

byte

export

import

private

synchronized

char

extends

int

protected

throws

class

final

interface

public

transient

const

float

long

short

volatile

 

7.2 JSON格式

 

JSON中对象是一个无序的“‘名称/集合。一个对象以{(左括号)开始,}(右括号)结束。每个名称后跟一个:(冒号);“‘名称/之间使用,(逗号)分隔,名称必须在双引号““内。

 

<!--[if gte vml 1]><v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"> <v:stroke joinstyle="miter"/> <v:formulas> <v:f eqn="if lineDrawn pixelLineWidth 0"/> <v:f eqn="sum @0 1 0"/> <v:f eqn="sum 0 0 @1"/> <v:f eqn="prod @2 1 2"/> <v:f eqn="prod @3 21600 pixelWidth"/> <v:f eqn="prod @3 21600 pixelHeight"/> <v:f eqn="sum @0 0 1"/> <v:f eqn="prod @6 1 2"/> <v:f eqn="prod @7 21600 pixelWidth"/> <v:f eqn="sum @8 21600 0"/> <v:f eqn="prod @7 21600 pixelHeight"/> <v:f eqn="sum @10 21600 0"/> </v:formulas> <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/> <o:lock v:ext="edit" aspectratio="t"/> </v:shapetype><v:shape id="_x0000_i1025" type="#_x0000_t75" style='width:366pt; height:69pt'> <v:imagedata src="file:///C:\Users\wn\AppData\Local\Temp\msohtmlclip1\01\clip_image001.png" o:href="file:///E:\Java\client\json\JSON.files\object.gif"/> </v:shape><![endif]--><!--[if !vml]--><!--[endif]-->

 

数组是值(value)的有序集合。一个数组以[(左中括号)开始,](右中括号)结束。值之间使用,(逗号)分隔。

 

<!--[if gte vml 1]><v:shape id="_x0000_i1026" type="#_x0000_t75" style='width:366pt; height:69pt'> <v:imagedata src="file:///C:\Users\wn\AppData\Local\Temp\msohtmlclip1\01\clip_image003.png" o:href="file:///E:\Java\client\json\JSON.files\array.gif"/> </v:shape><![endif]--><!--[if !vml]--><!--[endif]-->

 

值(value)可以是双引号括起来的字符串(string)、数值(number)truefalse null、对象(object)或者数组(array)。这些结构可以嵌套。

 

<!--[if gte vml 1]><v:shape id="_x0000_i1027" type="#_x0000_t75" style='width:366pt; height:170.25pt'> <v:imagedata src="file:///C:\Users\wn\AppData\Local\Temp\msohtmlclip1\01\clip_image005.png" o:href="file:///E:\Java\client\json\JSON.files\value.gif"/> </v:shape><![endif]--><!--[if !vml]--><!--[endif]-->

 

字符串(string)是由双引号包围的任意数量Unicode字符的集合,使用反斜线转义。一个字符(character)即一个单独的字符串(character string)。

 

字符串(string)与C或者Java的字符串非常相似。

 

<!--[if gte vml 1]><v:shape id="_x0000_i1028" type="#_x0000_t75" style='width:379.5pt; height:262.5pt'> <v:imagedata src="file:///C:\Users\wn\AppData\Local\Temp\msohtmlclip1\01\clip_image007.png" o:href="file:///E:\Java\client\json\JSON.files\string.gif"/> </v:shape><![endif]--><!--[if !vml]--><!--[endif]-->

 

数值(number)也与C或者Java的数值非常相似。除去未曾使用的八进制与十六进制格式。除去一些编码细节。

 

<!--[if gte vml 1]><v:shape id="_x0000_i1029" type="#_x0000_t75" style='width:372pt; height:165.75pt'> <v:imagedata src="file:///C:\Users\wn\AppData\Local\Temp\msohtmlclip1\01\clip_image009.png" o:href="file:///E:\Java\client\json\JSON.files\number.gif"/> </v:shape><![endif]--><!--[if !vml]--><!--[endif]-->

 

JSON格式的数据举例:

 

{

"anObject": {

        "numericProperty": -122,

        "stringProperty": "An offensive \" is problematic",

        "nullProperty": null,

        "booleanProperty": true,

        "dateProperty": "2011-09-23"

},

"arrayOfObjects": [

        {"item": 1},

        {"item": 2},

        {"item": 3}

],

"arrayOfIntegers": [1, 2, 3, 4, 5]

}

 

7.3 常用类型值举例

 

类型

举例值

描述

number

1

1.0

-5

le5

Math.PI

 

string

Hello

World

 

boolean

true

false

 

null

null

 

undefined

undefined

 

object

{}

{foo:abc, bar:123, baz:null}

{foo:bar}

对象字面量

new RegExp(hello)

/world/g

正则表达式

[]

[foo, 0.3, null]

数组

function f(x, y) {

return x*y;

}

普通函数

function User() {

}

new User();

构造函数

 

<!--[if !supportLists]-->7.4 <!--[endif]-->主流浏览器差异

 

目前主流的浏览器包括IEFireFoxChrome三种,其对JavaScript处理的有一定的差异,差异包括但不限于:

 

7.4.1 AJAX请求

 

IEFireFoxChrome浏览器中发起AJAX异步请求的对象不同:

 

IE

 

【示例】:

 

var xhr = new window.ActiveXObject( "Microsoft.XMLHTTP" );

 

FireFox\Chrome

 

【示例】:

 

var xhr = new window.XMLHttpRequest();

 

7.4.2 XML处理

 

IEFireFoxChrome浏览器中用于处理xml字符的对象不同:

 

IE

 

【示例】:

 

var xml = new ActiveXObject("Microsoft.XMLDOM" );

xml.async = false;

xml.loadXML( data );

 

FireFox/Chrome

 

【示例】:

 

var xml = new DOMParser().parseFromString( data , "text/xml" );

 

7.4.3 Table中动态添加行

 

IE中将tr添加到tbody才有效,如果添加到table则无效,FireFoxChrome支持两种方式,因此在开发跨浏览器应用时,建议采用添加到tbody的方式。

 

【示例】:

 

<table id="myTable">

<tbody id="myTableBody"></tbody>

</table>

 

<script>

var cell=null,

row=null;

 

cell= document.createElement("td");

cell.appendChild(document.createTextNode("foo"));

 

row= document.createElement("tr");

row.appendChild(cell);

 

document.getElementById("myTableBody").appendChild(row);

</script>

 

7.4.4 动态设置HTML元素样式

 

IE

 

【示例】:

 

<span id="mySpan">span内容 </span>

 

var spanElement = document.getElementById("mySpan");

spanElement.style.cssText = "font-weight:bold; color:red;";

 

FireFox/Chrome除了支持IE的实现方式外还可以通过setAttribute()实现

 

【示例】:

 

<span id="mySpan">span内容 </span>

 

var spanElement = document.getElementById("mySpan");

spanElement.setAttribute("style", "font-weight:bold; color:red;");

 

7.4.5 动态设置HTML元素样式类

 

IE

 

【示例】:

 

.myClass {

color:red;

}

 

<span id="mySpan">span内容 </span>

 

var spanElement = document.getElementById("mySpan");

spanElement.setAttribute("className", "myClass");

 

FireFox/Chrome

 

【示例】:

 

.myClass {

color:red;

}

 

<span id="mySpan">span内容 </span>

 

var spanElement = document.getElementById("mySpan");

spanElement.setAttribute("class", "myClass");

 

7.4.6 HTML元素动态注册事件处理器

 

IE

 

【示例】:

 

<div id="myDiv" style="width:200px;height:200px;background:red;"></div>

 

var divE = document.getElementById("myDiv");

divE.onclick = function() {

alertMsg();

};

 

function alertMsg() {

alert("单击div");

}

 

FireFox/Chrome支持IE的方式,并且也可以通过如下方式实现

 

【示例】:

 

<div id="myDiv" style="width:200px;height:200px;background:red;"></div>

 

var divE = document.getElementById("myDiv");

divE.setAttribute("onclick", "alertMsg()");

 

function alertMsg() {

alert("单击div");

}

 

7.4.7 动态创建单选按钮

 

IE6.0版本中,通过createElement创建一个input元素,再通过setAttribute设置input元素的type等属性的方式创建单选按钮,会出现如此被创建的单选按钮无法被选中,但是通过可以如下方式:

 

【示例】:

 

var radioButton=document.createElement("<input type='radio' name='radioButton'>");

document.getElementsByTagName("body")[0].appendChild(radioButton);

 

IE7+以及FireFoxChrome浏览器中通过如下方式创建单选按钮:

 

【示例】:

 

var radioButton = document.createElement("input");

radioButton.setAttribute("type", "radio");

radioButton.setAttribute("name",  "radioButton");

 

document.getElementsByTagName("body")[0].appendChild(radioButton);

 

7.4.8 事件

 

IE中的事件源:event.srcElement;

 

Firefox中的事件源:event.target;

 

Chrome中的事件源:event.srcElement/event.target

 

7.4.9 获取/设置DOM节点html内容、text内容

 

IEinnerHTMLinnerTextouterHTMLouterText

 

Firefox: innerHTMLtextContent(对应IEinnerText),无outerHTMLouterText

 

ChromeinnerHTMLinnerText/textContentouterHTMLouterText

 

7.4.10 获取DOM节点的自定义属性值

 

IEDOM元素.属性名称/DOM元素.getAttribute(属性名称);

 

Firefox/Chrome:DOM元素.getAttribute(属性名称)

 

【示例】:

 

<div role=”” id=”divId”/>

var elem = document.getElementById("divId ");

//适用于IE

elem.role;

//适用于IEChromeFireFox

elem.getAttribute(“role”);

//idDOM节点原生属性:适用于IEChromeFireFox

elem.id;

 

7.4.11 CheckBoxRadio的宽度、高度

 

以下是CheckBoxRadio在不同浏览器或者版本下的默认宽度、高度、padding值:

 

浏览器及版本

宽度(px)

高度(px)

padding(px)

IE7

20

20

0

IE8

13

13

3

Firefox

13

13

3

Chrome

13

13

3

 

如果需要支持IE7,则必须明确设置CheckBoxRadio的宽度、高度值为13px,并且明确设置padding值。

 

7.4.12 input button的样式

 

 表格中“空白”列对应的值指浏览器为按钮自动添加的空白像素

 

浏览器及版本

border

(px)

padding(px)

marginpx

font-size

(px)

空白

IE7

2

0

auto

13

每增加一个字就会增加空白,如果是双字节的字则增加空白比较多,如果是单字节的字则增加空白比较少,如图:

<!--[if gte vml 1]><v:shape id="_x0000_i1030" type="#_x0000_t75" style='width:63.75pt;height:154.5pt'> <v:imagedata src="file:///C:\Users\wn\AppData\Local\Temp\msohtmlclip1\01\clip_image011.png" o:title=""/> </v:shape><![endif]--><!--[if !vml]--><!--[endif]-->

IE8

3

1 8 1 8

auto

12

0px

<!--[if gte vml 1]><v:shape id="_x0000_i1031" type="#_x0000_t75" style='width:61.5pt;height:73.5pt'> <v:imagedata src="file:///C:\Users\wn\AppData\Local\Temp\msohtmlclip1\01\clip_image012.png" o:title=""/> </v:shape><![endif]--><!--[if !vml]--><!--[endif]-->

Firefox

3

0 6 0 6

0

13

3*2px(文字左边、右边分别3px的空白)

<!--[if gte vml 1]><v:shape id="_x0000_i1032" type="#_x0000_t75" style='width:60.75pt;height:72.75pt'> <v:imagedata src="file:///C:\Users\wn\AppData\Local\Temp\msohtmlclip1\01\clip_image013.png" o:title=""/> </v:shape><![endif]--><!--[if !vml]--><!--[endif]-->

Chrome

2

1 6 1 6

2

13

0px

<!--[if gte vml 1]><v:shape id="_x0000_i1033" type="#_x0000_t75" style='width:59.25pt;height:81.75pt'> <v:imagedata src="file:///C:\Users\wn\AppData\Local\Temp\msohtmlclip1\01\clip_image014.png" o:title=""/> </v:shape><![endif]--><!--[if !vml]--><!--[endif]-->

 

由上表可见如果需要兼容多浏览器,需要明确设置input button元素的border-size(注意:如果设置border样式会覆盖浏览器对border的默认设置,因此需要明确设置bordersize样式)、paddingmarginfont-size

 

7.4.13 table中的background样式

 

trtd中均设置了background样式时,IE78表现不同:

 

【示例】:

 

tr{

    background:red;

}

 

td{

    background:url() no-repeat;

}

 

按照以上示例的方式设置tdtr的背景样式,则在IE7tr的背景颜色不会应用到td中;IE8可以。

 

【示例】:

 

tr{

    background-color:red;

}

 

td{

background-image:url()

    background-repeat: no-repeat;

}

 

按照以上示例设置tdtr的背景样式,则IE7IE8表现相同。

 

因此推荐在设置背景等样式时推荐明确设置子项样式。

 

【示例】:

 

//

background-image:url()

background-repeat: no-repeat;

 

//

background:url() no-repeat;

 

7.4.14 设置background-image图片的位置

 

【示例】:

 

//

//IEFirefoxChrome支持

background-position:0 50%

 

//

//IEChrome支持

background-position-x:left;

background-position-y:center;

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics