Rebol真的具有javascript原型属性的等价物吗?

时间:2010-11-24 22:14:23

标签: javascript rebol

Gregogy在此发表了关于rebol和javascript的帖子http://blog.revolucent.net/2009/05/javascript-rebol.html

但是当我更深入地比较javascript和rebol时,我无法看到javascript原型的rebol相当于什么。因为使用make in rebol从另一个扩展对象实例并不完全像javascript原型属性,因为js prototype允许一次扩展所有实例。

所以我错了,或者是否有相当于以下代码的rebol:

<html>
<head>
</head>

<body>
  <script>        
    function Person(firstName, lastName, sex) {
      this.firstName = firstName;
      this.lastName = lastName;      
      this.whoAreYou = function() {
        alert( "I've been built with Constructor and my name is " + this.firstName + " " + this.lastName);
      }
      this.WhatIsYourSex = function() {
        alert(this.sex);
      }
    };

    Person.prototype.sex = "Man";

  </script>

  <script>
    JaneDoe = new Person("Jane", "Doe");
    JaneDoe.whoAreYou();
    JaneDoe.WhatIsYourSex();
    alert("Are you sure?");
    JaneDoe.sex = "Woman";
    JaneDoe.WhatIsYourSex();
  </script>

</body>
</html>

更新:我当然不关心语法糖。只需重新定义一个对象,就无法阻止R2中的扩展。我的问题不是关于对象INSTANCE的扩展,而是关于所有INSTANCES的扩展:这就是js prototype属性所允许的。

所以重新提出我的问题: Rebol是否允许通过扩展像javascript这样的父类来扩展子类的所有实例,无论我不关心什么语法?

为了性能确定我看到R2和R3之间的区别对于一个实例,但是对于语言功能我没有自动扩展所有子对象,这是一个很大的负担,因为我将不得不自己管理它们因为它不是由系统本身完成的,所以非常慢。如果我想创建一个像jquery这样严重依赖这种功能的框架怎么办?这将是一个很大的麻烦。

4 个答案:

答案 0 :(得分:7)

Oldes是对的,默认情况下,REBOL中不存在类似JS的原型。但您可以自由创建适合您需求的功能。下面是使用嵌套上下文在多个实例之间共享值来模拟JS原型的简单示例:

creature: func [
    /prototype
        field [word!]
        value [any-type!]
    /local result proto
][
    proto: [
        context [
            static: context [
                vars: reduce [
                    'kind "Monkey"
                ]
                extend: func [
                    blk [block!]
                    field [word!]
                    value [any-type!]
                    /local pos
                ][
                    either pos: find/skip blk field 2 [
                        change/only next pos :value
                    ][
                        insert/only insert tail blk reduce field :value
                    ]
                    :value
                ]

                get: func [
                    field [word!]
                ][
                    all [
                        field: any [
                            select/skip this/instance field 2
                            select/skip vars field 2
                        ]
                        first field
                    ]
                ]

                set: func [
                    field [word!]
                    value [any-type!]
                ][

                    extend this/instance field :value
                ]

                prototype: func [
                    field [word!]
                    value [any-type!]
                ][
                    extend vars field :value
                ]

                who-are-you: does [
                    print ["Hello I'm" this/get 'kind this/get 'sex this/get 'first-name join this/get 'last-name "."]
                ]
            ]

            instance: reduce [
                'first-name none
                'last-name none
            ]

            ;exported "API"
            get: system/words/get in static 'get
            set: system/words/get in static 'set
            prototype: system/words/get in static 'prototype
            who-are-you: system/words/get in static 'who-are-you

            this: none
        ]
    ]
    unless object? proto/1 [result: reduce proto append clear proto result] 

    if prototype [proto/1/prototype field :value]

    result: make proto/1 []
    result/this: result
]

creature/prototype 'sex "male"


jane: make creature []
jane/set 'first-name "Jane"
jane/set 'last-name "Rebol"

john: make creature []
john/set 'first-name "John"
john/set 'last-name "Doe"

jane/who-are-you

jane/set 'sex "female"

jane/who-are-you

john/who-are-you

creature/prototype 'kind "Human"

jane/who-are-you
john/who-are-you

答案 1 :(得分:6)

REBOL没有等效物。

R3中的对象是使用任何其他对象作为原型创建的。但是,一旦创建,它就是一个独立的实体。对用作原型的对象的更改不会影响较新的对象 - 反之亦然。

REBOL 2中的对象一旦创建,就不能添加新的字段;您所能做的就是基于旧对象创建一个新对象,但使用新字段。这可能很烦人,因为它可能会破坏对旧对象的引用。

REBOL 3在这方面要好得多。 扩展追加允许将新字段添加到任何对象。


这个脚本可能有点帮助:link text

  • 它将目标对象与a进行比较 引用对象,并添加任何 缺少字段:
  • 这是REBOL 2代码,所以目标 对象通过副本获得替换 而不是扩展
  • 但它会通过任何嵌套对象进行递归,因此它可以在一次传递中进行复杂的嵌套更改

答案 2 :(得分:3)

Rebol教程,你的反应包含太多“我不在乎”,你不觉得吗?顺便说一下,设计明智 - 在eart上有一个类定义的概念,它会在类实例化之后影响活动对象吗? : - )

那么 - 你真的做过任何测量,比较在循环中扩展相关对象的速度有多慢?您的声明“......会很慢”可能会显示为未经证实。

让我们做一些测量:

  
    

obj:context [a:1]     ==制作对象! [         a:1     ]

         

dt loop 1'000'000 [追加blk copy obj]     == 0:00:00.023372

         

长度? BLK     == 1000000

         

dt [foreach obj blk [append obj [b:2]]]     == 0:00:02.677348

         

长度? BLK     == 1000000

         

BLK / 1     ==制作对象! [         a:1         b:2     ]

         

BLK / 2     ==制作对象! [         a:1         b:2     ]

         

blk / 1 / a:3     == 3

         

BLK / 1     ==制作对象! [         a:3         b:2     ]

         

BLK / 2     ==制作对象! [         a:1         b:2     ]

  

因此,正如您所看到的,我设法在== 0:00:02.677348时间内使用自定义字段扩展了100万个对象。我4岁的机器。您的应用程序有多少个对象?

我知道这不是你想要的,因为你必须建立要扩展的对象列表,但它是一个启动者: - )

-pekr -

答案 3 :(得分:1)

我想你不会因为某种原因而不喜欢这个:

person: context [
    firstName: secondName: none
    whoAreYou: does [print [firstName secondName]]
    WhatIsYourSex: does [print sex]
]
extend person 'sex "male"
JaneDoe: make person [firstName: "Jane" secondName: "Doe"]
JaneDoe/whoAreYou
JaneDoe/WhatIsYourSex
ask "Are you sure?"
JaneDoe/sex: "female"
JaneDoe/WhatIsYourSex

我必须说,我不会在实际中使用这样的代码,因为我不明白我应该将数据与函数混合的原因。这只是模仿你的JS代码的尝试。

但我想,你有错误的例子,你想表明这一点:

<script>
    JaneDoe = new Person("Jane", "Doe");
    DoeJane = new Person("Doe", "Jane");
    Person.prototype.sex = "Man";
    JaneDoe.WhatIsYourSex();
    DoeJane.WhatIsYourSex();
</script>

我必须说,在REBOL中,至少现在还不支持这样的事情。