zoukankan      html  css  js  c++  java
  • 寄生构造函数——扩展原生数组

    最近在产品研发过程中,发现需要对原生数组进行一些扩展,我们深知修改原生对象的弊端,尤其在产品化的程序中修改原生对象的原型。如果因某个实现中缺少某个方法,就在原生对象的原型中添加这个方法,那么当在另一个支持该方法的实现中运行代码时,就可能会导致命名冲突。而且,这样做也可能会意外地重写原生方法,大名鼎鼎的prototype框架败因也在于此,改写了大量原生对象,当ECMAscript升级时,面临着许多改写方法与原生方法重名的问题,因此要不断地更改这些原有的扩展名称,导致一系列附带问题的出现。

    工作中对于这样的问题我采用了“寄生构造函数模式”对原生数组进行了扩展,虽然这种方法大家都不怎么使用,但是处理这种类型的问题,只有这种方式才最有效。如果采用传统的组合构造函数和原型模式,无形中也就犯了在原生对象上进行扩展的毛病,修改了原生数组。

    寄生构造函数模式到底是一种什么样子的呢?

    var myArray = function () {
                //创建一个新对象
                var arr = [];
                //获得某值的索引值
                arr.indexOf = function (item) {
                    for (var i = 0, len = arr.length; i < len; i++) {
                        if (arr[i] === item) {
                            return i;
                        }
                    }
    
                    return -1;
                };
                //检查某值是否在数组中
                arr.hasItem = function (item) {
                    return arr.indexOf(item) !== -1;
                };
                //不允许插入数组中已有的值,这里也可以传入一个数组
                arr.append = function (aItem) {
                    function _push(aItem) {
                        var aExt = [];
                        for (var i = 0, l = aItem.length; i < l; i++) {
                            if (!arr.hasItem(aItem[i])) {
                                arr.push(aItem[i]);
                            } else {
                                aExt.push(aItem[i]);
                            }
                        }
    
                        if (aExt.length > 0) {
                            alert(aExt.toString() + ' has in Array!');
                            aExt = null;
                        }
                    };
    
                    if ($.isArray(aItem)) {
                        _push(aItem);
                    } else {
                        _push(arguments);
                    }
    
                    return arr;
                };
                //移除某值,或某个数组
                arr.remove = function (aItem) {
                    function _splice(a) {
                        for (var i = 0, l = a.length; i < l; i++) {
                            var item = a[i];
                            if (arr.hasItem(item)) {
                                return arr.splice(arr.indexOf(item), 1);
                            }
                        }
                    };
    
                    if ($.isArray(aItem)) {
                        _splice(aItem);
                    } else {
                        _splice(arguments);
                    }
    
                    return arr;
                };
                //清空数组
                arr.clearAll = function () {
                    arr.length = 0;
                    return arr;
                };
                //在某个索引处插入某值
                arr.insert = function (target, indexPos) {
                    var len = arguments.length;
                    if (len == 2) {
                        var arg = arguments[0];
    
                        if (!arr.hasItem(arg)) {
                            arr.splice(arguments[1], 0, arg);
                        } else {
                            alert(arg + ' has in Array!');
                        }
                    } else {
                        alert('insert args count error!');
                    }
    
                    return arr;
                };
                //去除重复项
                arr.removeRepeat = function () {
                    var json = {}, res = [], l = arr.length;
                    if (l > 0) {
                        json[arr[0]] = true;
                        res.push(arr[0]);
    
                        for (var i = 1; i < l; i++) {
                            if (!json[arr[i]]) {
                                json[arr[i]] = true;
                                res.push(arr[i]);
                            }
                        }
                    }
    
                    return res;
                };
    
                //返回新对象,这个新对象重写调用构造函数时返回的值this
                return arr;
            };

    在这个例子中,myArray函数创建了一个新对象,并以相应的属性和方法初始化该对象,然后又返回了这个对象。除了使用new操作符并把使用的包装函数叫做构造函数之外,这个模式跟工厂模式其实是一模一样的。构造函数在不返回值的情况下,默认返回新对象实例。而通过在构造函数的末尾添加一个return语句,可以重写调用构造函数时返回的值this。

    关于寄生构造函数模式,有一点需要说明:首先,返回的对象与构造函数或者与构造函数的原型属性之间没有关系;也就是说,构造函数返回的对象与在构造函数外部创建的对象没有什么不同。为此,不能依赖instanceof操作符来确定对象类型。由于存在上述问题,所以通过这种模式创建的对象实例类型只能是object。

  • 相关阅读:
    synchronized锁机制 之 代码块锁(转)
    执行mvn 报错 source-1.5 中不支持 diamond运算符
    Git常用命令及场景
    mysql数据库导入与导出
    Linux磁盘空间分析及清理(df、du、rm)
    IIs配置文件存放路径
    解决SQLite database is locked
    C#测试web服务是否可用
    Jquery easyui-combobox 的一个BUG
    iframe自适应方法
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3324807.html
Copyright © 2011-2022 走看看