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这样严重依赖这种功能的框架怎么办?这将是一个很大的麻烦。
答案 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。
答案 2 :(得分:3)
那么 - 你真的做过任何测量,比较在循环中扩展相关对象的速度有多慢?您的声明“......会很慢”可能会显示为未经证实。
让我们做一些测量:
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中,至少现在还不支持这样的事情。