代码之家  ›  专栏  ›  技术社区  ›  mati

在Array.prototype中添加自定义函数

  •  83
  • mati  · 技术社区  · 17 年前

    我刚刚在Array.prototype中添加了一些方法,比如

    Array.prototype.doSomething = function(){
       ...
    }
    

    这可能是什么原因?我是否错过了修改标准件原型的一些东西?

    注意:我非常确定,当我修改Array的原型时,错误就开始了。它应该只与IE兼容。

    8 回复  |  直到 9 年前
        1
  •  94
  •   user137369    4 年前

    Object.defineProperty 方法,例如。

    // functional sort
    Object.defineProperty(Array.prototype, 'sortf', {
        value: function(compare) { return [].concat(this).sort(compare); }
    });
    
        2
  •  77
  •   thomasrutter    6 年前

    for .. in .

    使用示例进行说明(借用自 here ):

    Array.prototype.foo = 1;
    
    // somewhere deep in other javascript code...
    var a = [1,2,3,4,5];
    for (x in a){
        // Now foo is a part of EVERY array and 
        // will show up here as a value of 'x'
    }
    

    不幸的是,这样做的可疑代码的存在也使得有必要避免使用plain for..in 对于数组迭代,至少如果你想要最大的可移植性,只是为了防止其他一些讨厌的代码修改了数组原型。所以你真的需要两者都做:你应该避免平淡 为。.in 如果某些n00b修改了Array原型,您应该避免修改Array原型,这样就不会弄乱任何使用普通代码的代码 为。.in 迭代数组。

    Object.defineProperty ?

    现在存在 作为扩展对象原型而不枚举新属性的一般方法,尽管这仍然不能证明扩展 类型,因为即使除此之外 为。.in 仍然存在与其他脚本冲突的可能性。考虑有人使用两个Javascript框架,这两个框架都试图以类似的方式扩展Array并选择相同的方法名称。或者,考虑有人分叉 你的 然后将原始版本和分叉版本放在同一页面上。Array对象的自定义增强功能是否仍然有效?

    这就是Javascript的现实,以及为什么你应该避免修改内置类型的原型,即使是 .使用自己的构造函数定义自己的类型。

        3
  •  15
  •   Sylvain Rodrigue    3 年前

    fiddle demo

    让我们假设一个数组和一个返回第一个元素的foo方法:

    var myArray = ["apple","ball","cat"];
    
    foo(myArray) // <- 'apple'
    
    function foo(array){
        return array[0]
    }
    

    但是,这行不通:(因为原型尚未定义)

    myArray.foo() // <- 'undefined function foo'
    
    Array.prototype.foo = function(){
        return this[0]
    }
    

    为此,只需在顶部定义原型:

    Array.prototype.foo = function(){
        return this[0]
    }
    
    myArray.foo() // <- 'apple'
    

    add 数组的方法。

        4
  •  2
  •   Robert Koritnik    17 年前

        5
  •  0
  •   grabbag    7 年前

    function forEachWithBreak(someArray, fn){
       let breakFlag = false
       function breakFn(){
           breakFlag = true
       }
       function loop(indexIntoSomeArray){
    
           if(!breakFlag && indexIntoSomeArray<someArray.length){
               fn(someArray[indexIntoSomeArray],breakFn)
               loop(indexIntoSomeArray+1)   
           }
       }
       loop(0)
    }
    

    forEachWithBreak(["a","b","c","d","e","f","g"], function(element, breakFn){
        console.log(element)
    })
    

    生产 一 b d f 克

    测试2。..break在元素c之后被调用

    forEachWithBreak(["a","b","c","d","e","f","g"], function(element, breakFn){
        console.log(element)
        if(element =="c"){breakFn()}
    })
    

    生产 一 b c

        6
  •  0
  •   Edan Chetrit    4 年前

    1. 它是 for .. in )
    2. 潜力 (js、你自己、第三方等)

    1. 使用 Object.defineProperty
    2. 给一个 唯一标识符 对于我们的方法
    const arrayMethods = {
        doSomething: "uuid() - a real function"
    }
    
    Object.defineProperty(Array.prototype, arrayMethods.doSomething, {
        value() {
            // Your code, log as an example
            this.forEach(v => console.log(v))
        }
    })
    
    const arr = [1, 2, 3]
    arr[arrayMethods.doSomething]() // 1, 2, 3
    

    语法有点奇怪,但如果你想链接方法(只是别忘了 return this ):

    arr
        .map(x=>x+1)
        [arrayMethods.log]()
        .map(x=>x+1)
        [arrayMethods.log]()
    
        7
  •  0
  •   MrCADman    3 年前

    另一种选择是创建一个prototipe:

    Array.prototype.coalesce = function(){
        return this.find(a => a !== null);
    }
    
    [null, null, 1,2,3].coalesce();
    // returns 1
    
        8
  •  -1
  •   Jeremy Wall    17 年前

    如果你使用Prototype,情况尤其糟糕,因为Prototype也会扰乱全局范围,很难说你是否会发生冲突。实际上,即使在javascript中,修改任何语言的核心部分通常也是一个坏主意。