Dorado 9 : 01. JavaScript基础

JSON

JSON相当于Java世界里的POJO(相当于JavaScirpt中由List和Map组成的POJO)

基本语法:

var d = { prop1:"value", prop2:true };

相当于

var d = new Object(); // 也可以写作 var d = {};
d.prop1 = "value";
d.prop2 = true;

相对来说 var d= {};的写法更为简洁。Java程序员对上面的d.prop1="value"的实现不申明而直接使用的写法会觉得比较奇怪,但是JS中确可以这样使用,其实我们只要把JS中的Object想成Java的Map,d.prop1="value"就相当于d.put("prop1", "value");这样就容易理解多了,事实上JS在客户端的运行机制也和这个差不多,这样我们就可以给任意属性赋值。

我们再来看下面这个更为复杂的例子:

{
    name: "Phone",
    propertyDefs: [
        { name: "product", label: "型号", required: true },
        { name: "manufacturer", label: "生产商" },
        { name: "type", label: "机型", mapValues: [
            { key: "A", value: "直板" },
            { key: "B", value: "翻盖" },
            { key: "C", value: "滑盖" },
            { key: "D", value: "旋盖" },
            { key: "Z", value: "其它" }
        ]
        },
        { name: "price", label: "价格", dataType: "float" }
    ]
}

上面的代码给我们展示了一个多层的JSON对象,首先在顶层有两个属性,一个叫name,还有一个是propertyDefs。propertyDefs是一个数组,内部又放了很多个子对象,例如:

{ name: "product", label: "型号", required: true },
{ name: "manufacturer", label: "生产商" },

根据前面的JSON的学习我们知道申明一个对象即可以用new Object,也可以直接用{}.上面就通过这种方式申明了多个对象,且每个子对象有不同的属性。其中第三个子对象又包含了一个数组:

{ key: "A", value: "直板" },
{ key: "B", value: "翻盖" },
{ key: "C", value: "滑盖" },
{ key: "D", value: "旋盖" },
{ key: "Z", value: "其它" }

上面的JSON的分析,我们可以看出这是一个挺复杂的JSON对象,是一个树状结构的JSON,通过JSON我们可以很方便的创建一颗树形结构的对象。在AJAX越来越流行的今天,JSON更容易被开发人员所接受,也越来越多的在很多的开发框架中有所体现,作为一个默认的标准技术而存在。我们看刚才这个复杂的JSON结构,它既是一段JavaScript,又是用来描述数据的很好的格式。它比XML更为简洁,易读。

更详细的内容:

http://www.w3school.com.cn/json/index.asp

http://www.ibm.com/developerworks/cn/web/wa-lo-json/

闭包

关于闭包的定义非常晦涩难懂,因此我们通过下面的例子简单的介绍闭包

function a() {
    var text = "Hello!"
    function b() {
        alert(text);
    }
    setTimeout(b, 500);
}

上述代码定义了一个funciton a,但是a并不是我们要介绍的闭包,我们关注一下其内部的定义,首先它申明了一个text的变量,之后又定义了一个function b,在function b中使用了这个变量,function b中自己没有定义这个变量,而是直接使用了function外的text变量。但是在代码结束的地方并没有直接调用function b,而是采用了一个延时500毫秒再执行function b的写法,对于Java程序员可能会很奇怪text变量的使用,很容易得出如下的结论:“500毫秒的延时,function的调用应该已经结束了,如果结束的话私有变量text变量就应该已经被释放,从而导致function b无法访问到变量text”。你推测的没错,在Java的世界确实是这样,但是在JavaScript的世界就允许你这样使用。并且对这种用法中的function b在JavaScript中就被称为闭包函数。在JS中闭包函数可以访问所处环境中的局部变量。并且浏览器中的GC对于变量的回收处理也会有所差别,当它判断到一个局部变量被某一个闭包函数所引用时,JS引擎就会阻止该变量被GC回收。直到这个变量没有被引用。

闭包函数不一定需要命名,也可以是匿名函数,如:

setTimeout(function(){
    alert(text);
}, 500);

更多文档参考:

http://developer.51cto.com/art/200907/139159.htm

http://www.jb51.net/article/25737.htm

http://www.csser.com/dev/42.html

回调函数

回调函数最常见于Ajax操作和延时操作(如前面的例子)。通常都是利用闭包完成的。也就是说回调函数就是闭包的一种使用场景。在Dorado开发中会有较多地方使用到回调函数,如示例:

$ajax.request("data/phones.js", function(result) {
    grid.set("items", result.getJsonData());
});

上面的$ajax是Dorado中ajax调用的一个基本的工具类,我们调用其提供的request方法,方法找中的参数是一个URL。当这个URL请求结束后,$ajax工具类就会自动的触发内部的回调函数,由于是异步的,因此内部代码的执行是要等到ajax请求结束后才能进行。其中的grid等都是闭包机制中的局部变量,我们放心使用,不用担心局部变量被释放的问题。

如果是同步操作,代码往往是如下形式的:

var result = $ajax.requestSync("data/phones.js");
grid.set("items", result.getJsonData());

看得出,同步代码的格式更容易被程序员接受,代码似乎也更为简单。但是采用同步的运算方法和异步运算方法在浏览器中的执行效果会有很大差别,例如一个耗时5秒的http请求,如果采用同步处理机制,在这5秒内用户是不能做任何事情的,整个浏览器会完全卡住,使用户无法进行包括页面上的按钮单击,查询,表单输入等动作,必须等到ajax请求结束后才能进行,而采用异步处理方式,浏览器就允许在ajax执行的同时,还接受用户在界面上做的各种操作。而在5秒之后,回调函数依然会被触发进行正常的数据逻辑处理。AJAX技术本身强调就是要尽可能的采用异步技术。尽可能的确保界面的友好性,和更有效率的界面操作。

更多文档参考:

http://www.ityoudao.com/Web/Html_JS_646_1736.html

http://www.iteye.com/topic/301453

http://luxiao1223.blog.51cto.com/2369118/482885

http://bbs.51js.com/thread-85825-1-1.html