不鼓励对 JavaScript 原生类型进行原型设计?

Posted

技术标签:

【中文标题】不鼓励对 JavaScript 原生类型进行原型设计?【英文标题】:Prototyping JavaScript native types, discouraged? 【发布时间】:2011-03-06 08:12:12 【问题描述】:

javascript 的原生类型(如数组、字符串、数字等)中对附加功能进行原型设计是不是一个坏主意?

我认为拥有 myArr.pop() 等功能会很棒,但如果有一天它成为 ECMAScript x 的一部分——并且与我的实现不同,那么它可能会破坏整个软件?

【问题讨论】:

负责原型框架的人不这么认为。 如果做不到,他们不会让你做的。 【参考方案1】:

Prototype 是一个广泛扩展原生 Javascript 类型和 DOM 类的库,非常好地展示了扩展 Javascript 原生类型的优缺点。

优点:你会得到看起来很自然的 Javascript 代码。

坏处:您忘记了您实际上正在使用 Prototype - 当您切换到不使用 Prototype 的项目时会产生混乱。 (为什么我不能……哦,对了,那是原型能力。)

丑陋的:如果由于库、浏览器或规范冲突而导致方法定义(合同或签名不同的两种方法)发生冲突,您可能必须修改客户端代码以保持兼容性。这使得在已经被它们困扰的世界中需要考虑更多的兼容性。

为了兼容性和保持我自己的想法清晰,我个人避免扩展原生或 DOM javascript 类型,并且更喜欢侵入性较小的库而不是 Prototype。

但是,如果您对这些缺点感到放心,请不要让我阻止您。

【讨论】:

【参考方案2】:

如果您尝试复制为某些浏览器而不是其他浏览器定义的方法,请尝试使定义与本机实现相匹配。

if(![].indexOf)
    Array.prototype.indexOf= function indexOf(what, i)
        i= i || 0;
        var L= this.length;
        while(i< L)
            if(this[i]=== what) return i;
            ++i;
        
        return -1;
    

if(![].map)
    Array.prototype.map= function map(fun, scope)
        var L= this.length, A= Array(this.length), i= 0, val;
        if(typeof fun== 'function')
            while(i< L)
                if(i in this)
                    A[i]= fun.call(scope, this[i], i, this);
                
                ++i;
            
            return A;
        
        else throw 'missing function argument';
    

if(!''.trim)
    String.prototype.trim= function trim()
        return this.replace(/^\s+|\s+$/g,'');
    

如果可能,将使用本机方法。 如果您使用自己的方法,请尝试给它们起一个不太可能被抢占的名称

我喜欢对数组使用 shuffle 和 naturalSort 方法, 但我给他们的名字略逊一筹。

Array.prototype.a1Sort= function()
    var a, b, a1, b1, rx=  /(\d+)|(\D+)/g, rd=  /\d+/;
    return this.sort(function(as, bs)
        a= String(as).toLowerCase().match(rx);
        b= String(bs).toLowerCase().match(rx);
        while(a.length && b.length)
            a1= a.shift();
            b1= b.shift();
            if(rd.test(a1) || rd.test(b1))
                if(!rd.test(a1)) return 1;
                if(!rd.test(b1)) return -1;
                if(a1!= b1) return a1 - b1;
            
            else if(a1!= b1) return a1> b1? 1: -1;
        
        return a.length - b.length;
    );

Array.prototype.disorder= function(force)
    var i, temp, L= this.length, A= force? this: this.concat();
    while(--L)
        i= Math.floor(Math.random()*L);
        temp= A[i];
        A[i]= A[L];
        A[L]= temp;
    
    return A;

如果您确实添加到原型中,请确保将其记录在案并在使用它们的每个脚本中引用该文档- 如果有人会使用你的代码,包括你。

【讨论】:

以上是关于不鼓励对 JavaScript 原生类型进行原型设计?的主要内容,如果未能解决你的问题,请参考以下文章

如何理解JavaScript的原型和原型链

如何理解JavaScript的原型和原型链

Javascript中用来实现继承的几种方式

javascript中15种原生对象类型系统综述

原生JS讲解

JavaScript原型学习笔记