简体   繁体   English

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

[英]Does Rebol really have an equivalent for javascript prototype property?

Gregogy has made a post about rebol and javascript here http://blog.revolucent.net/2009/05/javascript-rebol.html Gregogy在这里发了一篇关于rebol和javascript的帖子http://blog.revolucent.net/2009/05/javascript-rebol.html

But as I'm going deeper into comparing javascript and rebol, I can't see what's the equivalent of rebol for javascript prototype. 但是当我更深入地比较javascript和rebol时,我无法看到javascript原型的rebol相当于什么。 Because extending an object instance from another one with make in rebol isn't exactly like javascript prototype property as js prototype allows to extend ALL instances at once. 因为使用make in rebol从另一个扩展对象实例并不完全像javascript原型属性,因为js prototype允许一次扩展所有实例。

So am I mistaken or is there an equivalent of the code below for rebol: 所以我错了,或者是否有相当于以下代码的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>

Update: I don't care about syntactic sugar of course. 更新:我当然不关心语法糖。 Nothing prevents extension in R2 by just redefining an object. 只需重新定义一个对象,就无法阻止R2中的扩展。 My question is not about extension of an object INSTANCE but about extension of ALL INSTANCES at once: that's what js prototype property allows. 我的问题不是关于对象INSTANCE的扩展,而是关于所有INSTANCES的扩展:这就是js prototype属性所允许的。

So to reformulate my question: Can Rebol allow to also extend AUTOMATICALLY ALL INSTANCES of children by extending the parent class like javascript can whatever the syntax I don't care ? 所以重新提出我的问题:Rebol是否允许通过扩展像javascript这样的父类来自动扩展子类的所有实例,无论我不关心什么语法?

For performance sure I see the difference between R2 and R3 for one instance but as for language functional feature I don't have automatic extension of all children objects which is a big burden as I'll have to manage them myself which will be quite slow since it's not done by the system itself. 为了性能肯定我看到一个实例的R2和R3之间的区别,但至于语言功​​能我没有自动扩展所有子对象,这是一个很大的负担,因为我将不得不自己管理它们将是非常慢因为它不是由系统本身完成的。 What if I want to create a framework like jquery which heavily relies on this kind of feature ? 如果我想创建一个像jquery这样严重依赖这种功能的框架怎么办? It would be a great hassle. 这将是一个很大的麻烦。

Oldes is right, the JS-like prototyping is not present in REBOL by default. Oldes是对的,默认情况下REBOL中不存在类似JS的原型。 But you are free to create own functionality that suits your needs. 但您可以自由创建适合您需求的功能。 Here is simple example that uses nested context for value sharing between multiple instances to simulate the JS prototyping: 下面是使用嵌套上下文在多个实例之间共享值来模拟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

REBOL does not have a equivalent. REBOL没有等价物。

An object in R3 is created using any other object as a prototype. R3中的对象是使用任何其他对象作为原型创建的。 But once, created, it is an independent entity. 但是,一旦创建,它就是一个独立的实体。 Changes to the object that was used as the prototype will not affect the newer object -- or vice versa. 对用作原型的对象的更改不会影响较新的对象 - 反之亦然。

Objects in REBOL 2, once created, cannot have new fields added to them; REBOL 2中的对象一旦创建,就不能添加新的字段; all you can really do is create a new object based on the old one, but with new fields. 您所能做的就是基于旧对象创建一个新对象,但使用新字段。 That can be annoying, as it may break references to the old object. 这可能很烦人,因为它可能会破坏对旧对象的引用。

REBOL 3 is much better in that way. REBOL 3在这方面要好得多。 extend and append allow new fields to be added to any object. extendappend允许将新字段添加到任何对象。


This script may help a little: link text . 这个脚本可能有点帮助: 链接文本

  • It compares an target object to a reference object, and adds any missing fields: 它将目标对象与引用对象进行比较,并添加任何缺少的字段:
  • It is REBOL 2 code, so the target object gets replaced by a copy rather than extended 它是REBOL 2代码,因此目标对象被副本替换而不是扩展
  • but it does recurse through any nested objects, so it can make complex nested changes in one pass 但它确实通过任何嵌套对象进行递归,因此它可以在一次传递中进行复杂的嵌套更改

Rebol Tutorial, your reactions contain too much of "I don't care", don't you think? Rebol Tutorial,你的反应包含太多“我不在乎”,你不觉得吗? And by the way, design wise - who on eart came with an idea of a class definition influencing live objects after class instantiation happened? 顺便说一下,设计明智 - 在eart上有一个类定义的概念,它会在类实例化之后影响活动对象吗? :-) :-)

So - did you actually do any measurements, to compare how slow it is to extend related objects in a loop? 那么 - 您是否真的进行了任何测量,以比较在循环中扩展相关对象的速度有多慢? Your claim " ... will be quite slow" might show as unsubstantiated. 你的声明“......会很慢”可能表明没有事实根据。

Let's do some measurements: 我们来做一些测量:

obj: context [a: 1] == make object! obj:context [a:1] == make object! [ a: 1 ] [a:1]

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

length? 长度? blk == 1000000 blk == 1000000

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

length? 长度? blk == 1000000 blk == 1000000

blk/1 == make object! blk / 1 ==制作对象! [ a: 1 b: 2 ] [a:1 b:2]

blk/2 == make object! blk / 2 ==制作对象! [ a: 1 b: 2 ] [a:1 b:2]

blk/1/a: 3 == 3 blk / 1 / a:3 == 3

blk/1 == make object! blk / 1 ==制作对象! [ a: 3 b: 2 ] [a:3 b:2]

blk/2 == make object! blk / 2 ==制作对象! [ a: 1 b: 2 ] [a:1 b:2]

So, as you can see, I managed to extend 1 million of objects with custom fields in == 0:00:02.677348 time. 因此,正如您所看到的,我设法在== 0:00:02.677348时间内使用自定义字段扩展了100万个对象。 I am on 4 years old machine. 我4岁的机器。 How many of objects your application have? 你的应用程序有多少个对象?

I know it's not what you probably want, as you have to build list of objects to extend, but it is a starter :-) 我知道这不是你想要的,因为你必须建立要扩展的对象列表,但它是一个启动器:-)

-pekr- -pekr-

I guess you will not like this from some reason: 我想你不会因为某些原因而不喜欢这个:

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

I must say, that I would not use code like this one in real as I don't see reason why I should mix data with functions. 我必须说,我不会在实际中使用这样的代码,因为我不明白我应该将数据与函数混合的原因。 It's just a try to mimic your JS code. 这只是模仿你的JS代码的尝试。

But I guess, you have wrong example and you want to show this: 但我想,你有错误的例子,你想要表明:

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

Than I must say, that in REBOL something like this is not supported, at least now. 我必须说,在REBOL中,至少现在还不支持这样的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM