博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
寄生构造函数——扩展原生数组
阅读量:5838 次
发布时间:2019-06-18

本文共 3849 字,大约阅读时间需要 12 分钟。

最近在产品研发过程中,发现需要对原生数组进行一些扩展,我们深知修改原生对象的弊端,尤其在产品化的程序中修改原生对象的原型。如果因某个实现中缺少某个方法,就在原生对象的原型中添加这个方法,那么当在另一个支持该方法的实现中运行代码时,就可能会导致命名冲突。而且,这样做也可能会意外地重写原生方法,大名鼎鼎的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。

转载地址:http://pljcx.baihongyu.com/

你可能感兴趣的文章
【阿里云文档】常用文档整理
查看>>
java中的Volatile关键字
查看>>
前端自定义图标
查看>>
实验二
查看>>
独立开发一个云(PaaS)的核心要素, Go, Go, Go!!!
查看>>
MyBatis使用DEMO及cache的使用心得
查看>>
网站文章如何能自动判定是抄袭?一种算法和实践架构剖析
查看>>
【OpenCV学习】滚动条
查看>>
ofo用科技引领行业进入4.0时代 用户粘性连续8个月远甩摩拜
查看>>
兰州青年志愿者“中西合璧”玩快闪 温暖旅客回家路
查看>>
计划10年建10万廉价屋 新西兰政府:比想象中难
查看>>
甘肃发首版《3D打印职业教育教材》:校企合作育专才
查看>>
为找好心人抚养孩子 浙江一离婚父亲将幼童丢弃公园
查看>>
晚婚晚育 近20年巴西35岁以上孕妇增加65%
查看>>
读书:为了那个美妙的咔哒声
查看>>
jsp改造之sitemesh注意事项
查看>>
iOS 9.0之后NSString encode方法替换
查看>>
ASMFD (ASM Filter Driver) Support on OS Platforms (Certification Matrix). (文档 ID 2034681.1)
查看>>
CRM Transaction处理中的权限控制
查看>>
[转]linux创建链接文件的两种方法
查看>>