Just some sharing about java open source and life

prototype.js 源码之扩展Object

日期:2010-09-07 23:16 | 作者:JavaChen | 分类目录:JavaScript
175 views

Object是其他对象实例的构造函数(var a=new Object()),也是所有其他类的父类,对Object直接扩展(注意不是扩展Object.prototype,扩展 Object.prototype相当于添加实例方法)相当于为Object类添加静态方法。

在对Object的扩展代码如下:

(function() {

  //Object对象的toString方法的引用
  var _toString = Object.prototype.toString;

  //属性拷贝
  function extend(destination, source) {
    for (var property in source)
      destination[property] = source[property];
    return destination;
  }

  //调用object的inspect(如果定义了)或toString方法,返回一个对象的字符串表示
  function inspect(object) {
    try {
      if (isUndefined(object)) return 'undefined';
      if (object === null) return 'null';
      return object.inspect ? object.inspect() : String(object);
    } catch (e) {
      if (e instanceof RangeError) return '...';
      throw e;
    }
  }

  function toJSON(object) {
    var type = typeof object;
    switch (type) {
      case 'undefined':
      case 'function':
      case 'unknown': return;
      case 'boolean': return object.toString();
    }

    if (object === null) return 'null';
    if (object.toJSON) return object.toJSON();
    if (isElement(object)) return;

    var results = [];
	//递归调用
    for (var property in object) {
      var value = toJSON(object[property]);
      if (!isUndefined(value))
        results.push(property.toJSON() + ': ' + value);
    }

    return '{' + results.join(', ') + '}';
  }

  //将一个对象转化为hash码
  function toQueryString(object) {
    return $H(object).toQueryString();
  }

  function toHTML(object) {
    return object && object.toHTML ? object.toHTML() : String.interpret(object);
  }

  //得到一个对象的所有属性名称
  function keys(object) {
    var results = [];
    for (var property in object)
      results.push(property);
    return results;
  }

 //得到一个对象的所有属性值
  function values(object) {
    var results = [];
    for (var property in object)
      results.push(object[property]);
    return results;
  }

 //克隆一个对象,返回新的对象
  function clone(object) {
    return extend({ }, object);
  }

  //判断一个对象是否是Element
  function isElement(object) {
    return !!(object && object.nodeType == 1);
  }

//判断一个对象是否是数组
  function isArray(object) {
    return _toString.call(object) == "[object Array]";
  }

//判断一个对象是否是Hash
  function isHash(object) {
    return object instanceof Hash;
  }

  function isFunction(object) {
    return typeof object === "function";
  }

  function isString(object) {
    return _toString.call(object) == "[object String]";
  }

  function isNumber(object) {
    return _toString.call(object) == "[object Number]";
  }

  function isUndefined(object) {
    return typeof object === "undefined";
  }

  extend(Object, {
    extend:        extend,
    inspect:       inspect,
    toJSON:        toJSON,
    toQueryString: toQueryString,
    toHTML:        toHTML,
    keys:          keys,
    values:        values,
    clone:         clone,
    isElement:     isElement,
    isArray:       isArray,
    isHash:        isHash,
    isFunction:    isFunction,
    isString:      isString,
    isNumber:      isNumber,
    isUndefined:   isUndefined
  });
})();

给一个对象增加一些属性和方法可以在其原型上增加,但是Prototype却并没有这么做,而是采用了现在广为流行的extend继承方式,jQuery和ExtJs也都采用了这种方式。
在上面代码中,定义了一个闭包,闭包内包括一些函数,为了将这些函数或是成为方法赋给Object对象,Prototype采用了extend机制。所谓extend,无外乎就是讲一个对象的属性和方法拷贝到另一个对象上去,这样另一个对象也就有了相同的属性和方法。

上面的代码中有对javascript各种对象类型的判断,其判断方式值得学习。
判断一个对象是否是函数,用typeof object === “function”,为什么不用“==”?因为“===”是全等运算符,其比较的是两个对象的值和类型,只有当两个对象的值和类型都相同时才是相等。需要注意到,在判断一个对象是否undefined时候,也是用到了“===”,如:typeof object === “undefined”
判断一个对象是字符串或是数字或是数组,采用了Object.prototype.toString.call()的方法,直接判断一个对象的字符串形式是否和目标对象(字符串或是数字或是数组)的字符串形式是否相同。

在闭包定义一些方法,然后在用extend方法将这些方法拷贝到Object对象,这样的话Object对象里就有了一些我们想要的方法了,这有点类似AOP的思想,往一个对象里注入我们想要的属性或方法。

看了上面的代码,让我想起来之前看到的一些类似的代码,下面这段代码来自于ExtJs的Ext.js文件。

        isArray: function(v){
            return Object.prototype.toString.apply(v) === '[object Array]';
        },

        isObject: function(v){
            return v && typeof v == "object";
        },

        isPrimitive: function(v){
            var t = typeof v;
            return t == 'string' || t == 'number' || t == 'boolean';
        },

        isFunction: function(v){
            return typeof v == "function";
        },
作者:JavaChen | 分类目录:JavaScript | 标签:
回到顶部

无觅相关文章插件,快速提升流量