У Rebol действительно есть эквивалент для свойства прототипа javascript? - PullRequest
5 голосов
/ 25 ноября 2010

Грегоги сделал пост о rebol и javascript здесь http://blog.revolucent.net/2009/05/javascript-rebol.html

Но поскольку я углубляюсь в сравнение javascript и rebol, я не вижу, что эквивалентно rebol для прототипа javascript.Поскольку расширение экземпляра объекта с другого с помощью make в 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 ]

7 голосов
/ 12 июня 2012

Олдес прав, JS-подобное прототипирование отсутствует в REBOL по умолчанию.Но вы можете создавать собственные функции, которые соответствуют вашим потребностям.Вот простой пример, который использует вложенный контекст для совместного использования значений между несколькими экземплярами для имитации прототипирования 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
6 голосов
/ 25 ноября 2010

REBOL не имеет эквивалента.

Объект в R3 создается с использованием любого другого объекта в качестве прототипа.Но однажды созданный, это независимая сущность.Изменения в объекте, который использовался в качестве прототипа, не будут влиять на более новый объект - или наоборот.

Объекты в REBOL 2, после создания, не могут иметь новые поля, добавленные к ним;все, что вы действительно можете сделать, это создать новый объект на основе старого, но с новыми полями.Это может раздражать, поскольку может нарушать ссылки на старый объект.

REBOL 3 намного лучше в этом смысле. extended и append позволяют добавлять новые поля к любому объекту.


Этот скрипт может немного помочь: текст ссылки .

  • Он сравнивает целевой объект с эталонным объектом и добавляет любые пропущенные поля:
  • Это код REBOL 2, поэтому целевой объект заменяется на накопия, а не расширенная
  • , но она распространяется через любые вложенные объекты, поэтому может вносить сложные вложенные изменения за один проход
3 голосов
/ 27 ноября 2010

Rebol Tutorial, ваши реакции содержат слишком много "Мне все равно", не так ли?И, кстати, мудрый дизайн - у кого возникла идея определения класса, влияющего на живые объекты после того, как произошло создание класса?: -)

Итак - вы действительно делали какие-либо измерения, чтобы сравнить, как медленно растягивают связанные объекты в цикле?Ваше утверждение "... будет довольно медленным" может показаться необоснованным.

Давайте сделаем несколько измерений:

obj: context [a: 1] == makeобъект![a: 1]

цикл dt 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 == make object![a: 3 b: 2]

blk / 2 == сделай объект![a: 1 b: 2]

Итак, как вы можете видеть, мне удалось расширить 1 миллион объектов с помощью пользовательских полей за время == 0: 00: 02.677348.Я нахожусь на 4-х летней машине.Сколько объектов у вашего приложения?

Я знаю, что это не то, что вы, вероятно, хотите, так как вам нужно создать список объектов для расширения, но это стартер: -)

-pekr-

1 голос
/ 30 ноября 2010

Полагаю, вам это не понравится по какой-то причине:

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 что-то вродеэто не поддерживается, по крайней мере сейчас.

...