这样两种写法都是合法的,但是意义完全不同, 第一个语句创建了一个新的变量,而第二个是定义了window对象的一个属性,相当于window.bar = 'otherthing';, 因此我们想使我们的Shaka具有这样的调用方式能力: $.someMethod();就需要将Shaka设置为window的一个属性, 于是我们的Shaka构造函数就得写成这样:
var Shaka = window.Shaka = window.$ = function(selector) { return new Shaka.fn.init(selector); };2. javascript的匿名函数.
创建并执行一个匿名函数的基本形式: (function(){ alert('Hello World!'); })(); 为什么要用到匿名函数呢,因为我们不想把Shaka的内部实现暴露出来,这样容易与其它代码冲突,只提供一个单一的入口,我们可以这样测试一下:
<script type="text/javascript"> (function(){ function privateFunction(){ alert('You can not see me, haha'); }; })(); function publicMethod() {alert('I am public');}; alert('匿名函数内部的函数是不可访问的, privateMethod 目前是: ' + typeof privateMethod); alert('全局函数可访, publicMethod 目前是: ' + typeof publicMethod); </script>然后,还有一个问题需要解决,俺们的框架做出来了但是还很简陋,在这之前我们需要让它与其它的框架协同工作,因此带来一个问题, 如果我们都使用$作为简写形式就会冲突了, 象jQuery一样,我们需要提供一个noConfilit的方法“出让”$的使用权。在我们的程序最开始处加入下面的代码:
var _$ = window.$;意思是将此前定义的$对象引用放到 _$ 中, 然后我们再给Shaka扩展一个方法出来, 如果其它开发者需要自行扩展的话也可以使用这个方式(jQuery的extend方法提供了更为强大的功能,请大家自行研究):
(function($){ //extend method definition. })(Shaka);
意思是将Shaka作为这个匿名函数的参数来调用这个方法。
前面我们讲过 Shaka.fn 就是 Shaka.prototype 的别名,因此我们要在Shaka.prototype 里面添加新的方法就可以写成这样:
现在我们来看一个完整的:
<form method="post" action="" name="myform"> <h1> 我几岁了?</h1> <br /> <input id="myInput" type="text" value="Hello world!" size="50" /> <br /><br /> <input id="otherInput" type="text" size="50" /> </form> <script type="text/javascript"> //我们在这里模拟一下在这之前如果加载了其它框架的情形, 这个时候window.$不为空. window.$ = { whoAmI: function(){ alert('This function result is from other js lib.');} }; (function(){ // 创建最外层匿名函数. window._$ = window.$;//将别的框架定义的$暂存. //给Shaka加上$ 的别名. var Shaka = window.Shaka = window.$ = function(selector) { return new Shaka.fn.init(selector); }; Shaka.fn = Shaka.prototype = { init: function(selector) { if(selector) this.selector = selector; return this; }, val: function(newValue) { //start val function body if(!(this.selector && this.selector.indexOf('#') == 0 && this.selector.length != 1)) return; //简单地判断传入值非法, 最好使用正则 var id = this.selector.substring(1); var obj = document.getElementById(id); if(obj)//如果对象存在 { if(newValue == undefined) return obj.value;//获取目标对象的值. obj.value = newValue;// 将目标对象的value属性设置为newValue. return this; //为了使方法可以连续调用, 返回当前实例。 } //end val function body } }; Shaka.fn.init.prototype = Shaka.fn; })(); //扩展新的方法. (function($){ //alert(obj.fn); $.noConflict = function(){ window.$ = window._$;//把$还给在开始处取得的引用. }; })(Shaka); //如果没有引入其它的框架,可以这么写 //alert('object old value is '+$('#myInput').val()); //alert($('#myInput').val('I am 3 years now!').val()); //强制使用完整名称. Shaka.noConflict(); alert('object old value is '+Shaka('#myInput').val()); alert(Shaka('#myInput').val('I am 5 years old now!').val()); //Shaka('#otherInput').val('这里的值是使用Shaka(\'#otherInput\').val()方法来写入的哦'); //或者可以这样写也行,仍然使用$, 把Shaka作为匿名函数的参数$传进去。 (function($){ //又可以用$了, 哈哈 $('#otherInput').val('这里的值是使用Shaka(\'#otherInput\').val()方法来写入的哦'); })(Shaka); //现在仍然可以使用$调用其它框架的方法. $.whoAmI(); </script>