• prototype.js 源码解读(01)


    prototype.js是一个设计的非常优雅且很有实用价值的js基础类库,其源码非常值得研究。研究它的源码不仅能提升个人水平,而且对你打下坚实的js基础也很有帮助。因本人技术水平有限,该解读仅供参考。


    定义全局对象Prototype,包括属性版本号,属性版本号的定义有利于版本号的检测
      9  var Prototype = {
      10     Version: '1.5.0',
      11     BrowserFeatures: {
      12          XPath: !!document.evaluate
      13     },
      14 
      15      ScriptFragment: '(?:<script.*?>)((
    |
    |.)*?)(?:</script>)',
      16      emptyFunction: function() {},
      17      K: function(x) { return x }
      18 };
    

    evaluate() 方法用来计算一个 XPath 表达式。

    ScriptFragment是正则表达式,用于捕获字符串中的<script>标记及其中的内容

    emptyFunction:是一个空函数,在后面经常会有用到

    K:返回参数自身的函数,后面会有应用


    20  var Class = {
    21      create: function() {
    22         return function() {
    23            this.initialize.apply(this, arguments);
    24        }
    25    }
    26 };
    

    用字面量的方法定义一个Class类,可以用来创建类。使用此模式创建的类能够实现构造函数。注意,这里的Class是大写,所以不是js的保留字,也不是构造函数。

    creat()方法:属性 create 是一个方法,返回一个构造函数。

    一般使用如下:

       var X = Class.create();    
    

    返回的构造函数会执行名为 initialize 的方法,此时的initialize方法还没有定义。


    28    var Abstract = new Object();//表示命名空间或者抽象类的东西
    29    
    30     Object.extend = function(destination, source) {
    31        for (var property in source) {
    32            destination[property] = source[property];//将source的所有属性复制到destination
    33        }
    34        return destination;
    35    };
    

    Abstract 的定义更多是为了保持命名空间清晰的考虑,也就是说,我们可以给 Abstract 这个对象实例添加新的对象定义。 Object其实是一个函数,他没有任何成员,所以是一个空类,所以Abstract也就没有任何成员。

    通过一个静态函数Object.extend(destination, source)实现了js中的继承。

    var a = new ObjectA(), b = new ObjectB();
    var c = a.extend(b);
    

    此时 c 对象同时拥有 a 和 b 对象的属性和方法。但是与多重继承不同的是,c instanceof ObjectB 将返回false


    37  Object.extend(Object, {
    38      inspect: function(object) {// 一个静态方法, 传入一个对象, 返回对象的字符串表示
    39         try {
    40            if (object === undefined) return 'undefined'; // 处理undefined情况
    41            if (object === null) return 'null'; // 处理null情况
    42            return object.inspect ? object.inspect() :   
    43  object.toString();
    44        } catch (e) {
    45            if (e instanceof RangeError) return '...';// 处理异常情况
    46            throw e;
    47        }
    48    },
    49        keys: function(object) { // 一个静态方法, 传入一个对象, 返回该对象中所有的属性, 构成数组返回
    50        var keys = [];//定义空数组,用来保存数据
    51        for (var property in object)
    52            keys.push(property);  // 将每个属性压入到一个数组中
    53        return keys;
    54    },
    55
    56    values: function(object) {//同上
    57        var values = [];
    58        for (var property in object)
    59            values.push(object[property]);
    60        return values;
    61    },
    62
    63    clone: function(object) { // 一个静态方法, 传入一个对象, 克隆一个新对象并返回
    64        return Object.extend({}, object);
    65     }
    66  });
    

    PrototypeObject类进行的扩展主要是通过静态函数Object.extend实现扩展。inspect主要是将对象转换为字符串做的一个检查,用到了try…catch语句。三目运算符中,如果对象定义了inspect方法(true), 则调用该方法返回(object.inspect()), 否则返回对象的toString()值。


    Function.prototype.bind = function() {
        var __method = this, args = $A(arguments), object = args.shift();
        return function() {
            return __method.apply(object, args.concat($A(arguments)));
        }
    }
    

    将函数绑定到某个对象运行,可在绑定的时候添加参数,例如:

    var obj1={p:"obj1"};
    var obj2={
            p:"obj2",
            method:function(args){
                    alert(args+this.p);
            }
    }
    obj2.method("this is ");//显示“this is obj2”;
    obj2.method.bind(obj1,"now this is ");//显示“now this is obj1”;
    

    Function.prototype.bindAsEventListener = function(object) {
        var __method = this, args = $A(arguments), object = args.shift();
        return function(event) {
            return __method.apply(object, [( event || window.event)].concat(args).concat($A(arguments)));
        }
    }
    

    bind一样,不过这个方法一般用做html控件对象的事件处理。所以要传递event对象
    假设有节点node1,则:

    node1.onclick=function(){
            clickHandler.bindAsEventListener(this)(event||window.event);
    }
    

    所有的数字类型都是Number类的实例,下面就是给Number类定义一些方法:

    Object.extend(Number.prototype, {
        /*
        将数字转换为颜色的形式
        */
        toColorPart: function() {
            var digits = this.toString(16);
            if (this < 16) return '0' + digits;
            return digits;
        },
    
        succ: function() {
            return this + 1;
        },
    
        times: function(iterator) {
            $R(0, this, true).each(iterator);
            return this;
        }
    });
  • 相关阅读:
    走了
    地表最简单安装MySQL及配置的方法,没有之一
    周总结
    Codeforces 1323 div2题解ABC
    Code force-CodeCraft-20 (Div. 2) D. Nash Matrix 详解(DFS构造)
    LeetCode 1293. Shortest Path in a Grid with Obstacles Elimination
    LeetCode 1292. Maximum Side Length of a Square with Sum Less than or Equal to Threshold
    LeetCode 1291. Sequential Digits
    LeetCode 1290. Convert Binary Number in a Linked List to Integer
    LeetCode 91. Decode Ways
  • 原文地址:https://www.cnblogs.com/zoucaitou/p/4284759.html
Copyright © 2020-2023  润新知