一、jQuery 写法优点
命名简单:一个 $ 就可以使用,我们命名的时候往往绞尽脑汁,像腾讯的 JX 阿里的 KISSY 雅虎的YUI 等等, 个人觉得都不如 jQuery 的 $ 和 underscore 的 _ 这样来的干脆,当然现在的这些个特殊符号都被各种库给占用了,我们也不得不绞尽脑汁的想其他命名了 >_<;
调用简单: jQuery 是函数式调用,比起一般的构造函数的 new XX() 这样去调用看起来爽的多;
扩展简单:直接 $.extend() 和 $.fn.extend() 就可以拓展,十分方便
二、简单实现一下:
function J(){ this.name = "J"; } var j = new J(); j.name;//"J"
这是我们面向对象编程的一般写法,先写一个构造器,之后new一个实例进行访问,原型什么的基础就不说了,显然这种调 用方法不是函数调用
那怎么实现函数式调用呢?返回一个实例:
function J(){ return new J(); }
那我们这样去调用?显然死循环,那么怎么办呢?
2. 把J当成工厂就可以了,用来生产我们要的实例,我们要生成的实例都放在prototype指向的函数就好了
var J = function(){ return new J.fn.init();//这样可以创造独立的作用域 } J.fn = J.prototype = { init:function(){ return this; }, name:44 }
把J作为工厂,返回的是 J.prototype.init 指向的 function, 为了保持好习惯使用简单,这里做了 J.fn = J.prototype,以后直 接处理 J.fn就可以了;
3. 这里的this指向的是 init的实例 ,那么是访问不到J.fn中的其他属性的,比如name ,那么怎么办呢?原型链:
J() 返回的是一个实例,那么调用不到将会去原型里面找,也就是 J.fn.init.prototype中去找,我们就可以将 J.fn.init.prototype 与 J.fn 连通,这样就可以访问 J.prototype 中的属性了:
var J = function(){ return new J.fn.init();//这样可以创造独立的作用域 } J.fn = J.prototype = { init:function(){ return this; }, name:44 } J.fn.init.prototype = J.fn;//可以访问J.prptotype原型 alert(J().name);//44
这就是 jQuery 函数式调用基本的思路了,init 可以传参等等就不管了,简单一个思路;
4. 扩展性:extend
jQuery 两种扩展,一种是 $.extend() ,一种是 $.fn.extend(), 分别扩展到 JQuery 和其原型中,实现的思路就是 this 的指向,看下面:
先做一个 类型判断,前面文章讲过的,后面会用到:
J.isType = function(type){ return function(obj){ return Object.prototype.toString.call(obj) == "[object "+ type +"]"; } } J.isObject = J.isType("Object");
之后写 extend
J.extend = J.fn.extend = function(){//{sss:function(){}}| "sss",function 只写这两种的了 var tmp = {}, key; var arg0 = arguments[0] || {}; if(typeof arg0 == "string"){ if(arguments[1]){ tmp[arg0] = arguments[1]; } }else if(J.isObject(arg0)){ tmp = arg0; } for(key in tmp){ this[key] = tmp[key]; } return tmp; }
测试一下
J.fn.extend("name", 333); console.log(J().name);//333 J.extend("callBacks",function(){}); J.callBacks;//function(){}
大致上就是这样的, jQuery就是在上面一点点扩展出来的,这里只是简单的一个思路,可以用这样的思路进行函数式调用编程。