【问题标题】:Query on usage of dictionary in JavaScript查询 JavaScript 中字典的使用情况
【发布时间】:2014-05-30 01:16:05
【问题描述】:

下面的代码是创建一个字典(foo),然后在字典中添加一个方法(bar)和属性名称ack

var foo = {};
foo.bar = function(){
     this.ack=3;
};
foo.bar();

在 python 中,如果我尝试做同样的事情,

>>> foo = {}
>>> def f():
    this.ack=3

>>> foo.bar = f
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    foo.bar = f
AttributeError: 'dict' object has no attribute 'bar'

我的问题:

  1. JavaScript 如何允许方法(bar)成为字典的成员,而不是(键,值)对?

  2. 另外,JavaScript如何让值为3的名称ack(这不是键值)成为字典的成员?

【问题讨论】:

  • 有苹果,也有橘子 :)
  • @thefourtheye 我没找到你

标签: javascript python dictionary


【解决方案1】:

JavaScript 如何让方法(bar) 成为字典的成员,而不是 (key, value) 对?

在 JavaScript 中,当你说

var foo = {};

你正在创建一个对象,当你分配类似的东西时

foo.bar = function(){
     this.ack=3;
};

它首先在foo 中查找bar。如果不是,它会创建一个新属性并将函数对象存储在其中。这里key为bar,value为函数对象。

但在 Python 中,您正在做一些完全不同的事情。您正在使用字典对象,当您执行foo.bar 时,它会在字典对象中查找bar 属性,因为它没有找到它,它会立即出错。

AttributeError: 'dict' object has no attribute 'bar'

如果您正在 Python 中寻找类似的行为,请使用这样的对象

class TempClass(object):
    pass

foo = TempClass()
def function():
    ack = 3
foo.f = function

另外,JavaScript 如何让值为 3(这不是 key-value)的 name ack 成为字典的成员?

现在,您正在处理 this 对象。 this 绑定是最近才发生的。当您调用ack 时,它会检查调用ack 的对象。因为它在foo 对象上,所以this 将被设置为foo。因此,您在 foo 上间接创建了一个新属性 ack

【讨论】:

  • 所以在 javascript 中,我们在没有类的帮助下创建对象及其层次结构(继承),而在 python 中,我们在类的帮助下创建对象。来自java背景(尽管是静态语言)你觉得这个怎么样?我们没有关于对象是什么的 OOP 范式的标准吗?类在创建对象之前是否应该存在?访问说明符是否需要类成员和方法?我们可以为对象添加动态属性吗?你认为这些概念是特定于语言的吗?
  • @Sham 除了一切都是对象的想法之外,Python 的对象必须从类中创建。所以类必须在对象之前创建。我们在 Python 中没有访问说明符。
  • 但在另一个层面上,javascript 允许我们在没有类的帮助的情况下创建对象。并引入了原型继承来创建层次结构。
  • @Sham 这就是为什么我说你在比较苹果和橘子:)
  • oh ok ):我猜,apple 和 orange 在两种语言中相同的 oop 范式的编程风格差异方面。我想,如果我不喜欢这样,我会得到的唯一答案是,写你自己的解释器。但我想没有选择苹果或橙色的选择,因为 javascript 是唯一的浏览器语言,而 python 对于服务器端程序来说不是一个糟糕的选择
【解决方案2】:

JavaScript 没有字典类型。你用{} 创建的是一个对象。您可以为对象分配属性,例如:

var foo = {};
foo.func1 = function () {};
foo['func2'] = function () {};
var a = 'func3';
foo[a] = function () {};

【讨论】:

  • 别忘了过去的 (function (o) {o.baz = 'hello';}(foo));(function () {this.fizz = 'world'}).call(foo);
【解决方案3】:

首先,不要将 JavaScript {} 视为 dict。这是一个 Object,它更接近于 Python 的 class

您可以像这样向的实例添加方法

from types import MethodType as bind

class Foo():
    pass

def bar(self):
    self.ack = 3

foo = Foo()
foo.bar = bind(bar, foo) # add method bar to foo as property bar
foo.bar()
foo.ack # 3

Python 中,设置继承实际上“更容易”,因为您不需要 import 任何东西

Foo.baz = bar
foo.baz() # invokes inherited bar as expected

【讨论】:

    【解决方案4】:

    我认为您混淆了字典、对象和对象属性。在 javascript 中,var foo = {}; 是一个对象。您可以通过foo.bar; 访问该对象的属性在python 中,foo = {} 是一个字典,而不是一个对象。当您在 python 中说 foo.bar 时,这没有任何意义,因为字典没有名为 bar 的实例变量。

    Python 可以将函数引用存储在字典中:

    >>> foo['bar'] = lambda x: x*x
    >>> foo['bar'](10);
    100
    

    【讨论】:

    • picky-mode: "foo = {} 是字典,不是对象。" - f = {}; f.__class__.__base__ &lt;type 'object'&gt;
    • 是的,这是一种挑剔的模式,但我接受当大多数东西都是对象时,字典也是。让我想知道为什么原始数字不是对象。
    • 试试 (5).__class__ ... 5.__class__ 是一个无效的浮点字面量。
    【解决方案5】:

    JavaScript 中的{} 是一个对象,当你写的时候:

    foo.bar = function(){}; // property/method-name : value
    

    它设置对象foobar方法,并且:

    foo.name = "Something"; // property/method-name : value
    

    foo 对象的name 属性设置为"Something"

    Python 中的{} 是一个字典,在其中你可以:

    foo = {}
    
    def f():
        foo["ack"] = 3 # key-value here
    
    foo["bar"] = f
    
    foo["bar"]()
    
    print foo["ack"] # 3
    

    如果您想在 Python 中复制点的行为,请使用:

    class Foo:  # constructor for objects
        pass
    
    def f(self):      # `self` = object
        self.ack = 3  # object has properties
    
    obj = Foo()  # object
    
    obj.bar = f # object has methods
    
    # passing object as parameter,
    # or you need to do `bind` as illustrated by Paul S. in his answer
    obj.bar(obj)  
    
    print obj.ack # 3
    

    【讨论】:

    • gaurang 是 'def f(): this.ack = 3' 吗?
    • @Sham 哦,那是一个错字。感谢您的通知。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多