2011年3月12日星期六

javascript中的this关键字

下面这段是从jQuery Fundamental中copy过来的。
The this keyword

In JavaScript, as in most object-oriented programming languages, this is a special keyword that is used within methods to refer to the object on which a method is being invoked. The value of this is determined using a simple series of steps:

1. If the function is invoked using Function.call or Function.apply, this will be set to the first argument passed to call/apply. If the first argument passed to call/apply is null or undefined, this will refer to the global object (which is the window object in Web browsers).
2. If the function being invoked was created using Function.bind, this will be the first argument that was passed to bind at the time the function was created.
3. If the function is being invoked as a method of an object, this will refer to that object.
4. Otherwise, the function is being invoked as a standalone function not attached to any object, and this will refer to the global object.

我觉得比较好的解释了this的意义。其中第三和第四是经常碰到的情况。其实它还漏了一种经常发生的情况情况,那就是constructor function中this的意思。对于constructor function,this代表new出来的对象,一开始是空,最后返回给调用者。看例子吧:

// For constructor function, 
// you could add the first and the last line, 
// or browser will add them for you defaultly.
foo = function(x){
   // this = {}; 
   this.x = x; 
   // return this; 
}; 

bar = new foo(); 

jQuery源码学习

jQuery是一个非常优秀的javascript库,前一段时间YUI和jQuery有过一场争论,其实我觉得它们都还不错,只是适用的地方不同。对于小型的简单的应用,jQuery的开发效率是非常高的。我们废话少说,进入正题吧。

对于大多数人来说它就像一个magic black box,但jQuery是如何工作的,可能研究的人就不多了。本文稍微谈一下,jQuery源码,以及它的工作原理。

jQuery的源码host在github.com上,现在正在处于1.5向1.6的开发阶段。将master branch拉下来make一下,就可以在dist目录下看到jquery.js了。或者如果你更愿意看分模块的code,就直接到src下看。

Overview
打开jquery.js,它的基本结构是这样的:
// This is an self-executing anonymous function
(function(window, undefined) {
    var jQuery = (function() {
        var jQuery = function(selector, context) {
            return new jQuery.fn.init(selector, context, rootjQuery);
        },
            rootjQuery;

        jQuery.fn = jQuery.prototype = {
            constructor: jQuery,
            init: function(selector, context, rootJQuery) {
                // ...
                return this;
            }
            // ...
        };

        jQuery.fn.init.prototype = jQuery.fn;

        return jQuery;
    })();
    
    // ...

    window.jQuery = window.$ = jQuery;

})(window);

// alert($());

Self-executing anonymous function
最外层是一个自执行的匿名函数(self-executing anonymous function)。它有两个作用:
  1. 作为一个匿名的namespace。在函数内部的变量不再是全局变量,不会影响到其他库和用户代码,也不会受它们的影响。
  2. 防止恶意程序改写undefined(javascript允许重新定义这个关键字,evil feature),一个简单的例子如下。jQuery定义了一个两个参数的函数,调用的时候只传一个。保证了函数中的undefined一定是“真的”undefined。



函数内部第3行定义了一个内部对象jQuery,第25行将这个对象export到global space,赋值给window.$和window.jQuery。然后$("#id")就可以work了。

第3-21行又定义了一个自执行的匿名函数,作用一样,是一个namespace,在jQuery不同模块之间做隔离。第4行再次定义了一个jQuery,在第20行返回了这个jQuery。这个jQuery就是最终用户得到的对象(函数也可以认为是对象)。



What jQuery is?
这个jQuery是个什么呢?

它是一个function(同时又是一个constructor function和object),所以以下三种用法都是可以的。



可以看到作为function和constructor function它的意义是一样的,它会返回一个jQuery.fn.init的对象。
jQuery.fn.init在第12行定义,它做的事情就是parse输入的selector和context,返回jQuery对象。这个名字比较绕,其实可以把jQuery.fn.init看作一个整体就好理解多了。第9-18行其实可以理解成下面一行代码。不管你的object是new $("#id")还是$("#id"),对它们调用的方法会落到这个prototype中。

(jQuery.fn.init).prototype = jQuery.fn = jQuery.prototype = { 
    //... 
}; 

Extending jQuery
因此如果要在上述object上扩展一个方法,很简单

// The following notations are OK as well:
// $.fn.init.prototype.new_func
// $.prototype.new_func
$.fn.new_func = function() {
    // ...
}

当然jQuery提供了专门的方法($.fn.extend)做这件事情。

另外我们还看到$.browser这样的方法。要扩展这样的方法同样很简单

$.new_func() = function() {
    // ...
}

同样,jQuery提供了专门的方法($.extend)做这件事情。

这里大家也发现了,jQuery有两类方法,$("").xxx和$.xxx。在jQuery的官方文档上它也是加以区分的,
Resources
一些比较好的资源:

    2011年3月11日星期五

    Hello world

    Hello, world