第一类工厂与哈希对象

来源:Ruby's Louvre 时间:2009-12-28 13:14:00 

第一类工厂相当于mootools的Native方法,用于创建一些具有扩展能力的类,但这些类并没有继承能力,此类工厂也不能以某个类作为蓝本创建子类。总之,一切从简。第一类工厂要依赖一些辅助方法,一并写出来了。


var dom = {},//命名空间slice = Array.prototype.slice;dom.mixin = function (obj, bag) {  if (arguments.length === 1) {    bag = obj;    obj = this;  };  if (obj && bag && typeof bag === 'object') {    for (var p in bag) {      if(bag.hasOwnProperty(p))        obj[p] = bag[p];    }  };  if (!+"\v1") {//IE不能在for...in循环中遍历toString与valueOf属性,需要单独处理    var t = bag.toString,v = bag.valueOf,op = Object.prototype;    if (bag.hasOwnProperty("toString") && typeof t === "function" && t !== op.toString)      obj.toString = t;    if (bag.hasOwnProperty("valueOf") && typeof v === "function" && v !== op.valueOf)      obj.valueOf = v;  }  return obj;};dom.factory = function(obj){//第一类工厂  var init = obj.init,  klass = function() {    if(arguments.length === 1 && arguments[0] instanceof klass)      return arguments[0];    return new klass.fn.init(arguments);  }  klass.fn = klass.prototype = {    init :init,    constructor: klass  };  klass.fn.init.prototype = klass.fn;  delete obj.klass;delete obj.init;  dom.mixin(klass.fn, obj);  //用于扩展原型方法  klass.mixin = function(bag){    dom.mixin(this.fn,bag);    return this;  };  klass.alias = function(oldName, newName){    var bag = {};    if (dom.isString(oldName) && dom.isString(newName)){      var method = this.fn[oldName]      if (!!method){        bag[newName] = method;        return this.mixin(bag);      };    };    //如果是一个属性包,如Hash.alias({keyOf: 'indexOf', hasValue: 'contains'});    bag = oldName;    for (var name in bag)      if(bag.hasOwnProperty(name))        this.alias(name,bag[name]);    return this;  };  klass.staticizeWithout = function(arr){    var conditions = {},keys = arr || [],me = this;    for(var i=0,n = keys.length;i>n;i++){      conditions[keys[i]] = 1;    }    dom.each(me.fn,function(method, name){      if(!conditions[name] && dom.isFunction(me.fn[name]) && dom.isUndefined(me[name])&&        name !== 'init' && name !== 'toString' && name !== 'valueOf' ){        me[name] = function () {          var args = dom.toArray(arguments),          caller = args.shift();          method.name = name; //为其泛化方法添加一个name属性          return method.apply(me(caller), args);        }      }    });    return me;  }  return klass;};dom.mixin(new function(){  var _toString = Object.prototype.toString,  _slice = Array.prototype.slice,  _push = Array.prototype.push,  is = function(obj,type) {    return _toString.call(obj).match(/^\[object\s(.*)\]$/)[1] === type;  }  return {    isArray: function (obj) {      return is(obj,"Array");    },    isFunction: function (obj) {      return is(obj,"Function") ;    },    isNumber: function (obj) {      return is(obj,"Number") ;    },    isString: function (obj) {      return is(obj,"String") ;    },    isUndefined: function (obj) {      return  obj === void(0);    },    each: function (obj, fn, bind) {      for (var key in obj) //只遍历本地属性        if (obj.hasOwnProperty(key))          fn.call(bind, obj[key], key, obj);    },    isArrayLike : function (obj) {//包括Array      if(dom.isArray(obj) || obj.callee) return true;      if(is(obj,'NodeList')) return true;      if(is(obj,'HTMLCollection')) return true;      //不能为字符串,不能为window,具有length属性      if(dom.isNumber(obj.length) && !dom.isString(obj) && !obj.eval){        if(obj.nextNode || obj.item)          return true;        var n = obj.length - 1 > 0 ? 0 : obj.length - 1 ;        //如果是具有数字键或length属性的对象,如jQuery对象        if(obj.hasOwnProperty(n) && obj.hasOwnProperty(0))          return true        return false;      }      return false;    },    toArray : function (arr) { //把普通对象变成原生数组对象      if(arguments.length === 0 || arr === null){        return [];      }else if(arr.callee){//如果是Arguments对象        return _slice.call(arr);      }else if(dom.isArray(arr)){//如果Array对象返回一个克隆        return arr.concat();      }else if(dom.isArrayLike(arr)){        try{//jQuery对象,dom对象,el.getElementsByTagName得到的HTMLCollection          //与el.childNodes得到的NodeList          return _slice.call(arr);        }catch(e){//IE用slice处理元素或节点集合会出错,只能慢慢拷贝          var ret = [], i = arr.length;          while (i) ret[--i] = arr[i]; //Clone数组          return ret;        }      }else {//普通函数,单个元素节点,字符串,数字,window对象        return [arr];      }    },    setArray: function (els) { //把普通对象变成类数组对象      this.length = 0;      _push.apply(this, els);      return this;    }  }});

这样dom就有如下几个方法mixin,factory,isArray,isArrayLike,isFuction,isNumber,isString,isUndefined,toArray,each,走实用主义路线,像isObject基本没有用。最新版的jQuery1.4a2好像加了两个特别的验证方法,isPlainObject(验证其是javascript core的Object而非宿主对象或DOM对象)与isEmptyObject(空对象,有点像{},但要保证其原型没有被扩展)。

标签:工厂,哈希,对象,mootools,JavaScript
0
投稿

猜你喜欢

  • 手机网站开发必修课[2009总结版]

    2010-01-05 17:02:00
  • 防止网站被采集的理论分析以及十条方法对策第1/2页

    2011-03-29 10:38:00
  • ASP与数据库应用(给初学者)

    2009-03-09 18:32:00
  • 利用ASP从远程服务器上接收XML数据

    2007-08-23 12:49:00
  • Oracle客户端 NLS_LANG 的设置方法

    2012-07-11 15:55:27
  • ASP实现类似Java中的Linked HashMap类

    2010-04-03 20:49:00
  • 探索网页设计中的黄金比例

    2008-10-20 12:26:00
  • ASPError(err)对象的相关基础知识

    2008-03-24 20:23:00
  • 一个ASP记录集分页显示的例子

    2007-09-14 10:57:00
  • ASP 操作cookies的方法

    2011-03-10 11:24:00
  • 基于AJAX技术提高搜索引擎排名

    2008-01-24 12:45:00
  • 百度、谷歌和雅虎的近日LOGO

    2008-05-19 12:11:00
  • 使用SqlBulkCopy时应注意Sqlserver表中使用缺省值的列

    2012-07-11 15:34:35
  • Oracle 10g的DBA无法登录解决方案

    2009-05-24 19:38:00
  • asp日期 时间 星期函数使用方法详解

    2007-09-21 17:38:00
  • Script块放在另一个Script 块内方法

    2009-02-04 15:43:00
  • asp入门之字符串函数介绍示例

    2008-11-04 20:18:00
  • 在windows下 1045 access denied for user

    2010-03-04 11:44:00
  • 谈谈网页设计中的字体应用 (3) 实战应用篇·上

    2009-11-24 13:09:00
  • 10个糟糕的IE Bug及其修复

    2010-05-13 16:26:00
  • asp之家 网络编程 m.aspxhome.com