首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  程序员

JavaScript 是否可以让数组支持负数索引?

  •  1
     
  •   sdjl · 41 天前 · 2175 次点击
    这是一个创建于 41 天前的主题,其中的信息可能已经有所发展或是发生改变。

    假如我想让数组支持负数索引,实现如下效果

    let a = [1,2,3];
    console.log(a[-1]); // 3
    

    提示:这样做可能会有问题,例如和其他程序员写的模块冲突,但是我们现在不管这个事情,就是想知道能不能实现。

    我目前写了段如下的代码

    const pyArray = function(a){
        return new Proxy(a, {
          get: function(target, prop, receiver) {
            let index = Number(prop);
            if (index < 0) {
                prop = String(target.length + index);
            };
            return Reflect.get(target, prop, receiver);
          }
        });
    };
    
    let a = [1, 2, 3];
    let b = pyArray(a)
    
    console.log(b[-1]); // 3
    console.log(a[-1]); // undefined
    

    这里虽然用 Proxy 实现了类似的效果,但是并没有改变原生数组的行为。

    能不能改写原生数组的行为,让 a[-1]也能返回 3 ?

    13 回复  |  直到 2019-10-04 22:23:59 +08:00
        1
    optional   41 天前   ♥ 3
    不行
        2
    jamesliu96   41 天前 via Android
    应该只能用 Proxy
        3
    airyland   41 天前
    原生数组的行为是不能变化了,只能对封装对象有效。不过这样的话和直接写工具函数没什么区别了,还不用考虑兼容问题。
    https://github.com/sindresorhus/negative-array
        4
    love   41 天前
    别在内置对象上加功能是共识。

    另外你这个改变也有不兼容风险,毕竟如果有库依赖-1 得到 undefined 的行为呢
        5
    xuanbg   41 天前
    这样的需求意义何在?
        6
    scnace   41 天前 via Android
    这个不符合语义啊
        7
    Mutoo   41 天前   ♥ 1
    不要太依赖原生的函数,或者是语法糖。
    且不说 js 数组的原生函数超级混乱,有时直接修改原数组,有时返回的是浅拷贝。
    不如自己实现函数式接口更加方便,简单几行就能实现。

    pyGet = (arr, idx) => arr[(idx+arr.length)%arr.length];
    pyGet([1,2,3], -1) // 3

    柯里化一下就更通用了

    pyGet = currying((arr, idx) => arr[(idx+arr.length)%arr.length]);
    // or pyGet = arr => idx => arr[(idx+arr.length)%arr.length]);

    a = pyGet([1,2,3]);
    a(-1); //3

    与原生相比,上面的写法不会更费劲。
    另外 a = [1,2,3] 本质是 a = new Array(1,2,3); 的语法糖。
    这也是为什么 js 没有办法提供[]的代理或重载(语法糖层面)。
        8
    shakespaces   41 天前 via Android
    还得判断一下负数绝对值大于 length 的时候的问题。。。
        9
    starsriver   41 天前 via Android
    可以加引号。arr["-b"]

    有什么意义吗?
        10
    starsriver   41 天前 via Android
    我的意思是,做倒序存进去,用索引。
        11
    Mutoo   41 天前
    @shakespaces 其实不用,正取溢出 undefined, 负取溢出也应该是 undefined
        12
    l1nyanm1ng   40 天前 via iPhone
    arr[arr.length - 1]不就是倒数第一个元素了,同理 arr[arr.length - 2]就是倒数第二个元素了,py 的语法糖不过如此
        13
    sdjl   40 天前
    @xuanbg 只是研究一下 JS 语言
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1252 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 22ms · UTC 23:25 · PVG 07:25 · LAX 15:25 · JFK 18:25
    ♥ Do have faith in what you're doing.