Javascript 如何重载方法和处理键

Javascript How to overload a method and handle keys

我正在尝试实现一个类似于 Python 的字典。所以,我想要一个 keys() 方法,将 returns 键添加到 subclass Dict,但不包括对象方法 "keys"

等属性

再次编辑 基本上,我正在制作一个 class 以将设置传递给函数(如 function(arg1, arg2, myObj)),其中我的对象是 {map: texMap, alphaMap: aTexMap}。它适用于 Three.js,我必须等待图像下载后才能在 3D 对象上创建设置。因此,界面就像人们期望的 var d = { a: aData b: bData } 中的 d 一样,但隐藏了用户未添加的方法等。

即当 own 通过时不要 return this.prototype.propertyName

这是我目前的情况:

function Dict(){
    this.prototype = {};
    var _keys = this.prototype.keys;
    this.keys = function(own){
        if(typeof own === 'undefined') { return _keys(); }
        var ownKeys = [];
        for(var key in _keys()){
            if(this.hasOwnProperty(key)) {
                ownKeys.push(key);
            }
        }
        return ownKeys;
    }
}

这会像下面这样工作吗?有更好的或已经存在的方法吗?

关于这个主题,我可能最关心的是保存原型方法作为获取所有键并过滤掉原型键的方法。

另外,我读过 Javascript 中没有内置重载功能。但是,我发现的大部分内容都与独立功能有关,例如 this Q&A on best practices. 我不需要内置方式,但我会利用任何可用的方式(因此,使用 Object 作为 Dict)。

欢迎任何反馈!

编辑 在 Python 中,我们得到:

In[2]:  d = {}
In[3]:  'has_key' in d.keys()
Out[3]: False
In[7]:  'has_key' in d.__class__.__dict__.keys()
Out[7]: True
In[8]:  d.has_key('has_key')
Out[8]: False
In[9]:  d['newKey'] = 5
In[10]: d.newKey  # ERROR

Python 在其 class 中包含一个 dict 属性,其中函数通过点访问(参见 In[8]...) .因此,那些标准的 {} 或 dict() 函数和运算符是隐藏的(不是私有的),而 keys/data 添加到用户的字典中是通过 [] 访问的。 d['newKey'] = 5 添加新密钥或覆盖旧密钥并将数据设置为 5.

我不需要所有这些都可以工作,尽管它会很棒。 keys() returning Python-like 键现在就可以了。

这里似乎有多个问题。

您似乎想将可变参数传递给函数:

I'm making a class to pass settings to a function like function(arg1, arg2, myObj) where my object is {map: texMap, alphaMap: aTexMap}.

JS函数参数非常灵活

  • 您可以为它们中的每一个设置名称:

    function foo(arg1, arg2, map, alphaMap)
    

    并直接传值。这种风格适用于处理一组固定参数的函数。

  • 或者您可以设置一个 "options" 对象来收集键和值:

    function foo(options)
    

    并通过{arg1: val1, arg2: val2, map: valMap, alphaMap: valAlphaMap}。这种风格经常出现在构造函数中,这些构造函数使用特定的设置配置选项初始化对象。

  • 或者你可以设置一个空函数签名

    function foo() 
    

    并在函数内使用 arguments 集合。这在使用可变数量的统一参数(想象 add(1, 2, 3, 4, 6))或严格位置参数而不是命名参数的函数中发现。

在任何情况下,向函数传递参数在 JavaScript 中都是可选的,即使函数签名中有参数列表也是如此。您可以自由传递 none,更少或更多的参数。当然,如果适合你,所有这些方法都可以结合使用。


It's for Three.js, and I have to wait on images to download before I can create settings on 3D objects.

这是网络的异步特性导致的问题。解决方案是使用事件处理程序。这些要么是回调,要么是 - 作为回调的抽象 - 承诺。


So, interface like one would expect with d in var d = { a: aData b: bData }, but hide the methods etc that are not added by the user.

这可以通过不向数据对象添加方法等来解决,或者至少不直接添加。如果您的数据对象必须具有行为,请将它们添加到原型中。


Python Dict 的直接等价物是 JavaScript 中的普通对象。

var dict = {};

Python 的 keys() 方法的直接等价物是 JavaScript 中的 Object.keys() 静态方法。

var keys = Object.keys(dict);

要迭代键,您可以使用命令式方法:

var i, key;
for (i = 0; i < keys.length; i++) {
    key = keys[i];
    doSomething(key, dict[key]);
}

或功能性

keys.forEach(function (key) {
    doSomething(key, dict[key]);
});

Python 的 in 的直接等价物是 JavaScript 中的 .hasOwnProperty():

if ( dict.hasOwnProperty('foo') ) ...

或者,如果是没有原型链的纯数据对象,也可以使用in

if ('foo' in dict)

不推荐在 for 循环中使用 in,因为它也会迭代原型属性。防止这种情况的方法是改用 Object.keys() 或将其与 .hasOwnProperty() 结合使用。

var key;
for (key in dict) {
    if ( dict.hasOwnProperty(key) ) ...
}

您的问题表明您缺少有关 JS 的基本拼图,请尝试用更熟悉的 Python 构造来替代它们。我建议不要那样做。

我还怀疑你试图把Python的基于class的继承模式硬塞进JS的基于原型的继承模式。我强烈建议您也不要这样做。