&QUOT与......;声明,扩展原型 [英] "with" statement, extending prototype

查看:78
本文介绍了&QUOT与......;声明,扩展原型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近在查看原型库

http:/ /prototype.conio.net/ )我注意到作者使用了

以下语法:


Object.extend(MyObj.prototype, {

my_meth1:function(){},

my_meth2:function(){}

});

在MyObj原型对象上定义新方法。 Object.extend

简单地合并传入的两个对象。在这种情况下,MyObj.prototype

是我们的空原型对象,对象文字就是我们的内容

合并。我真的很喜欢这种方法超过标准:

MyObj.prototype.my_meth1 = function(){};

MyObj。 prototype.my_meth2 = function(){};


我喜欢它因为它允许我使用对象初始化器来定义我的

对象(更短,不容易出错并保持我的代码DRY)但是

它不会压缩对象上已有的任何属性(种类

感觉就像Ruby中的开放类功能)。唯一不需要使用函数来进行合并的东西。所以我想b / b
想到了一个没有这个问题的替代实现,但仍然具有相同的优势。如果我们做了什么:


with(MyObj.prototype){

function my_meth1(){}

function my_meth2() {}

}


我的理解是


函数myfunc(){

}


完全相同


var myfunc = function(){}


与以下内容完全相同:


<当前范围对象> .myfunc = function(){}


当然大部分时间你都无法访问范围上的顶级项目

链,但这就是我理解在幕后发生的事情。

因为与"语句将我自己的对象放在范围的顶部

链似乎在with块中定义的任何函数都会导致在指定对象上创建一个新属性

。这应该允许

我做我想做的事情而不使用任何特殊功能(只需内置

的东西)。


所以我决定尝试这个实验,它似乎失败了。我按如下方式定义了我的

对象:


var Car = function(){}

with(Car.prototype){

函数start(){

alert(''starting'');

}

}

mycar = new Car();

mycar.start();


这给我一个关于开始的错误没有在mycar上定义。我用
永远不会在with语句中出现任何错误。似乎

函数在with块中定义,不会被添加到Car

原型对象中。


任何人都有任何建议或想法。我在

Firefox下测试了这个理论。


Eric

I was recently looking at the prototype library
(http://prototype.conio.net/) and I noticed the author used the
following syntax:

Object.extend(MyObj.prototype, {
my_meth1: function(){},
my_meth2: function(){}
});

to define new methods on the MyObj prototype object. Object.extend
simply merges the two objects passed in. In this case MyObj.prototype
is our empty prototype object and the object literal is what we are
merging in. I really like this approach over the standard:

MyObj.prototype.my_meth1 = function(){};
MyObj.prototype.my_meth2 = function(){};

I like it because it allows me to use object initializers to define my
object (which is shorter, less error prone and keeps my code DRY) but
it doesn''t squash any already existing properties on the object (kind
of feels like the open classes feature in Ruby). The only thing I don''t
like about it is the need for using a function to do the merge. So I
got thinking of an alternate implementation that doesn''t have this
problem but still has the same advantages. What if we did:

with(MyObj.prototype) {
function my_meth1(){}
function my_meth2(){}
}

It is my understanding that

function myfunc() {
}

is the exact same as

var myfunc = function(){}

which is the exact same as:

<current scope object>.myfunc = function() {}

Of course most of the time you can''t access the top item on the scope
chain but that is what I understand to be happening behind the scenes.
Since the "with" statement puts my own object at the top of the scope
chain it seems that any functions defined in the with block would cause
a new property to be create on the specified object. This should allow
me to do what I want without using any special function (just builtin
stuff).

So I decided to try this experiment and it seemed to fail. I define my
object as follows:

var Car = function() {}
with(Car.prototype) {
function start() {
alert(''starting'');
}
}
mycar = new Car();
mycar.start();

This gives me an error about "start" not being defined on mycar. I
never get any errors with the with statement. It just seems that
functions defined in the with block don''t get added to the Car
prototype object.

Anybody got any suggestions or ideas. I tested this theory under
Firefox.

Eric

推荐答案

em******@gmail.com 在05/04/2006 1:23 PM AEST上说:
em******@gmail.com said on 05/04/2006 1:23 PM AEST:
我最近在查看原型库
http ://prototype.conio.net/ )我注意到作者使用了以下语法:

Object.extend(MyObj.prototype,{
my_meth1 :function(){},
my_meth2:function(){}
});

在MyObj原型对象上定义新方法。 Object.extend
只是简单地合并传入的两个对象。在这种情况下,MyObj.prototype
是我们的空原型对象,对象文字是我们合并的。我真的很喜欢这种方法超过标准:

MyObj.prototype.my_meth1 = function(){};
MyObj.prototype.my_meth2 = function(){};

我喜欢因为它允许我使用对象初始化器来定义我的
对象(它更短,更不容易出错并保持我的代码干燥)但是它不会压缩对象上已有的任何属性(感觉就像Ruby中的开放类功能一样。我唯一不喜欢的是需要使用函数来进行合并。所以我想到了一个没有这个问题的替代实现,但仍然具有相同的优势。如果我们这样做了:

with(MyObj.prototype){
函数my_meth1(){}
函数my_meth2(){}
}

我的理解是

函数myfunc(){
}


var myfunc =完全相同function(){}


不*完全*相同,第一个是函数声明,第二个是
是一个函数表达式。使用表达式,名称(标识符)是可选的,因此更接近匹配:


var myfunc = function myfunc(){};


一个区别是Gecko的JS引擎为

函数的参数对象分配了一个name属性。如果函数是匿名的,则名称

属性为空。对于函数声明不是这样,它必须具有

的标识符(IE不提供arguments.name属性)。


似乎没什么意义使用函数表达式,如果没有使用它的特殊性 - 例如条件评估:


var someFunc;

if(...){

someFunc = function(){/ * body 1 * /};

}其他{

someFunc = function(){/ * body 2 * /};

}


与以下内容完全相同:

<当前范围对象> .myfunc = function(){}


哪个''当前范围对象''是什么,一个对象?它相当于

为对象的myfunc属性分配一个匿名函数。


当然大部分时间你都无法进入顶层范围内的项目



难道不是顶级项目总是全球性的对象吗?或者你的意思是''这个'?


但这是我理解在幕后发生的事情。
因为with声明将我自己的对象放在范围的顶部


不是那么多''在顶部''但是在当前

执行的范围链之前上下文。


链似乎在with块中定义的任何函数都会导致在指定对象上创建新属性。这应该允许我做我想做的事情而不使用任何特殊功能(只是内置
东西)。

所以我决定尝试这个实验,它似乎失败了。我将我的
对象定义如下:

var Car = function(){}
with(Car.prototype){
function start(){
警告(''开始'');
}
}
mycar = new Car();
mycar.start();

这给我一个关于开始的错误没有在mycar上定义。我b $ b

不完全是。它给出了''mycar.start不是函数'的错误,其中我认为它几乎相当于
。 :-)


永远不会在with语句中出现任何错误。似乎在with块中定义的函数不会被添加到Car
原型对象中。


没有错误,因为它有效。该功能确实被添加,但作为一个

的私人会员,不是公开的 - Mike Winter或者有人可以解释

如何运作,而不是我!你已经有效地完成了:


var Car = function(){

function start(){

alert(''starting '');

}

}

你现在需要做的是添加一个特权方法来调用start():


Car.prototype.callStart = function(){start()};

var aCar = new Car();

aCar。 callStart(); //显示''开始''

现在它''有效',但是不值得推荐只是为了满足一些

编码偏好 - 特别是因为它需要一个非首选的

语句才能使其正常工作,这违背了目的。


使用''with''并保持start()公开,你可以使用:


with(Car){

prototype.start = function(){alert(''starting'');};

}


但这似乎是一种不好的方法:


Car.prototype.start = .. 。


任何人都有任何建议或想法。我在Firefox下测试了这个理论。
I was recently looking at the prototype library
(http://prototype.conio.net/) and I noticed the author used the
following syntax:

Object.extend(MyObj.prototype, {
my_meth1: function(){},
my_meth2: function(){}
});

to define new methods on the MyObj prototype object. Object.extend
simply merges the two objects passed in. In this case MyObj.prototype
is our empty prototype object and the object literal is what we are
merging in. I really like this approach over the standard:

MyObj.prototype.my_meth1 = function(){};
MyObj.prototype.my_meth2 = function(){};

I like it because it allows me to use object initializers to define my
object (which is shorter, less error prone and keeps my code DRY) but
it doesn''t squash any already existing properties on the object (kind
of feels like the open classes feature in Ruby). The only thing I don''t
like about it is the need for using a function to do the merge. So I
got thinking of an alternate implementation that doesn''t have this
problem but still has the same advantages. What if we did:

with(MyObj.prototype) {
function my_meth1(){}
function my_meth2(){}
}

It is my understanding that

function myfunc() {
}

is the exact same as

var myfunc = function(){}
Not *exactly* the same, the first is a function declaration, the second
is a function expression. With an expression, the name (identifier) is
optional, so a closer match is:

var myfunc = function myfunc(){};

One difference is that Gecko''s JS engine assigns a name attribute to the
function''s arguments object. If the function is anonymous, the name
attribute is empty. Not so for a function declaration, which must have
an identifier (IE doesn''t provide an arguments.name property).

There seems little point to using a function expression if none of its
specialness is being used - e.g. conditional evaluation:

var someFunc;
if (...){
someFunc = function(){ /* body 1 */ };
} else {
someFunc = function(){ /* body 2 */ };
}

which is the exact same as:

<current scope object>.myfunc = function() {}
Where ''current scope object'' is what, an object? It is equivalent to
assigning an anonymous function to the myfunc property of the object.

Of course most of the time you can''t access the top item on the scope
chain
Isn''t the ''top item'' always the global object? Or do you mean ''this''?

but that is what I understand to be happening behind the scenes.
Since the "with" statement puts my own object at the top of the scope
Not so much ''at the top'' but before the scope chain of the current
execution context.

chain it seems that any functions defined in the with block would cause
a new property to be create on the specified object. This should allow
me to do what I want without using any special function (just builtin
stuff).

So I decided to try this experiment and it seemed to fail. I define my
object as follows:

var Car = function() {}
with(Car.prototype) {
function start() {
alert(''starting'');
}
}
mycar = new Car();
mycar.start();

This gives me an error about "start" not being defined on mycar. I
Not exactly. It gives the error ''mycar.start is not a function'', which
I guess is pretty much equivalent. :-)

never get any errors with the with statement. It just seems that
functions defined in the with block don''t get added to the Car
prototype object.
No errors because it ''works''. The function does get added, but as a
private member, not public - Mike Winter or someone can likely explain
how that works, not me!. You have effectively done:

var Car = function(){
function start(){
alert(''starting'');
}
}
What you need to do now is add a privileged method to call start():

Car.prototype.callStart = function(){start()};
var aCar = new Car();
aCar.callStart(); // shows ''starting''
Now it ''works'', but it''s not worth recommending just to satisfy some
coding preference - especially since it requires a non-preferred
statement to make it work, which defeats the purpose.

To use ''with'' and keep start() public, you can use:

with (Car){
prototype.start = function(){alert(''starting'');};
}

but that just seems like a bad way to do:

Car.prototype.start = ...;


Anybody got any suggestions or ideas. I tested this theory under
Firefox.




我也是,但对于IE来说也一样。

-

Rob

小组常见问题:<网址:http://www.jibbering.com/FAQ>



Me too, but its the same for IE.
--
Rob
Group FAQ: <URL:http://www.jibbering.com/FAQ>


首先我我想感谢您的反馈。我是多年来误解Javascript的程序员之一,直到最近开发的Ajax库(例如原型)已经向我展示了
$

Javascript有多酷。我还在努力了解所有

的详细信息,所以我非常感谢对我理解的任何更正。


RobG写道:
First I want to thank you for your feedback. I am one of the waves of
programmers who misunderstood Javascript for many years until the
recent development of Ajax libraries (such as prototype) have showed me
just how cool Javascript can be. I''m still trying to understand all the
details so I greatly appreciate any corrections to my understanding.

RobG wrote:
与以下内容完全相同:

<当前范围对象> .myfunc = function(){}
其中''当前范围对象' '是什么,一个对象?它等同于将匿名函数分配给对象的myfunc属性。
which is the exact same as:

<current scope object>.myfunc = function() {}
Where ''current scope object'' is what, an object? It is equivalent to
assigning an anonymous function to the myfunc property of the object.




<当前范围对象>引用添加到范围的最后一项

chain。我认为在当前范围内创建的标识符实际上是添加到范围链中的最后一项的属性。也许这是我的误解。



<current scope object> referred to the last item added to the scope
chain. I thought identifiers created in the current scope were really
properties of the last item added to the scope chain. Maybe this is my
misunderstanding.

当然,大部分时间你都无法访问顶级项目范围
Of course most of the time you can''t access the top item on the scope
chain



不是''顶级项目''始终是全球对象?或者你的意思是''这个'?



Isn''t the ''top item'' always the global object? Or do you mean ''this''?




来自top item我的意思是添加到范围链中的最后一个项目(我是这么想的,就像一个堆栈,当你进入和退出时,对象被弹出和关闭

范围链功能)。

没有错误,因为它有效。该功能确实得到了补充,但作为一个私人会员,而不是公众 - 迈克·温特或某人可能会解释这是如何运作的,而不是我!


嗯......我不确定我是否理解这个私人与公共成员的东西。

将不得不对它进行一些阅读。感谢您指向我正确的

方向。

要使用''with''并保持start()公开,您可以使用:

with(Car){
prototype.start = function(){alert(''starting'');};
}



By "top item" I meant the last item added to the scope chain (I am
thinking about it like a stack with objects being popped on and off the
scope chain as you enter and exit functions).
No errors because it ''works''. The function does get added, but as a
private member, not public - Mike Winter or someone can likely explain
how that works, not me!.
Hmmm.... I''m not sure I understand this private vs public member stuff.
Will have to do some reading on it. Thanks for pointing me in the right
direction.
To use ''with'' and keep start() public, you can use:

with (Car){
prototype.start = function(){alert(''starting'');};
}




我不确定我理解为什么:


with(Car){

prototype.start = function(){alert(''starting'' );};

}


不等于:


with(Car.prototype) {

start = function(){alert(''starting'');};

}


再次感谢如需反馈,


Eric



I''m not sure I understand why:

with (Car) {
prototype.start = function() {alert(''starting'');};
}

isn''t equivilant to:

with (Car.prototype) {
start = function() {alert(''starting'');};
}

Once again thanks for your feedback,

Eric



em ****** @ gmail.com 写道:


[snip]

em******@gmail.com wrote:

[snip]
我不确定我理解为什么:

with(Car){
prototype.start = function(){alert(''starting'');};
}

不等于ivilant to:

with(Car.prototype){
start = function(){alert(''starting'');};
}
I''m not sure I understand why:

with (Car) {
prototype.start = function() {alert(''starting'');};
}

isn''t equivilant to:

with (Car.prototype) {
start = function() {alert(''starting'');};
}



[/ snip]


粗略地说,当带时声明找到标识符,例如

" prototype"或者开始,在{]内,它试图找到提供给with语句的对象的相应

属性。但它是什么呢?b $ b不能做,就是创建一个新的属性对象,如果它找不到

一个。


所以: -


with(Car){

prototype.start = function(){alert(''starting'');};

}


有效,因为原型是Car的现有属性。


因此它相当于Car.prototype.start =,这是一个

JavaScript有效方式创建一个名为start的新属性。





with(Car.prototype){

start = function(){alert(''starting'');};

}


不起作用,因为start不是

" prototype"的现有属性,并且JavaScript无法猜测你想要创建一个新属性。
想要创建一个新属性。对于所有JavaScript都知道,开始可以

同样是先前声明的变量或者你想要为其分配值的新的全局变量。


上述代码的作用是创建一个新的全局代码。变量

称为开始,而Car.prototype保持不变。


问候


Julian Turner


[/snip]

In rough terms, when the "with" statement finds an "identifier", e.g.
"prototype" or "start", within the { ] it tries to find a corresponding
property of the object supplied to the with statement. But what it
does not do, is create a new property of the object, if it cannot find
one.

So:-

with (Car) {
prototype.start = function() {alert(''starting'');};
}

works, because "prototype" is an existing property of Car.

So it becomes the equivalent of "Car.prototype.start=", which is a
JavaScript valid way of creating a new property named "start".

and

with (Car.prototype) {
start = function() {alert(''starting'');};
}

does not work, because "start" is not an existing property of
"prototype", and there is no way that JavaScript can guess that you
want to create a new property. For all JavaScript knows, "start" could
equally be a previously declared variable or a new global variable you
are wanting to assign a value to.

The effect of the above code is to create a new "global" variable
called "start", and Car.prototype remains unchanged.

Regards

Julian Turner


这篇关于&QUOT与......;声明,扩展原型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆