My book (Flanagan's JavaScript: The Definitive Guide, 5th ed.) implies on page 111 that the following two constructs are equivalent:
( x.constructor == Foo )
and
( x instanceof Foo )
The author states that the instanceof operator computes its result by examining the value of its first argument's the constructor property.
However, I've recently ran into a situation that contradicts this.
I've been trying to understand jQuery better, with the aid of Firefox's Firebug debugger. At one breakpoint, there's one variable (I'll call it x) for which
x instanceof jQuery
is true, but
x.constructor == jQuery
is false.
In fact, x.constructor is Object, but (Object instanceof jQuery) is false.
Could anyone explain to me what's going on?
TIA!
Kynn
-- NOTE: In my address everything before the first period is backwards; and the last period, and everything after it, should be discarded.
> My book (Flanagan's JavaScript: The Definitive Guide, 5th ed.) > implies on page 111 that the following two constructs are equivalent:
> ( x.constructor == Foo )
> and
> ( x instanceof Foo )
> The author states that the instanceof operator computes its result > by examining the value of its first argument's the constructor > property.
> However, I've recently ran into a situation that contradicts this.
> I've been trying to understand jQuery better, with the aid of > Firefox's Firebug debugger. At one breakpoint, there's one variable > (I'll call it x) for which
> x instanceof jQuery
> is true, but
> x.constructor == jQuery
> is false.
> In fact, x.constructor is Object, but (Object instanceof jQuery) > is false.
> Could anyone explain to me what's going on?
> TIA!
> Kynn
> -- > NOTE: In my address everything before the first period is backwards; > and the last period, and everything after it, should be discarded.
I know that there are difference in the way that instanceof is determined vs. x.constructor. In this instance it sounds like it's an issue with the way that JQuery handles it's extends functionality. Not having used JQuery a great deal, could you shed some light on the way that JQuery extends?
In <7a310b71-b65d-42b6-9bd0-fee6d18ba...@e10g2000prf.googlegroups.com> "liamge...@gmail.com" <liamge...@gmail.com> writes:
>I know that there are difference in the way that instanceof is >determined vs. x.constructor. In this instance it sounds like it's an >issue with the way that JQuery handles it's extends functionality. Not >having used JQuery a great deal, could you shed some light on the way >that JQuery extends?
That went over my head! :-) But I'll do my best...
The jQuery object does have an extend method, if that's what you're asking. It can be invoked in a few ways, but probably the most general one is something like
If bool is false, extend copies values from obj1, obj2, obj3, etc. into the corresponding slots in target. If bool is true, instead of copying it extends the slots when the the contents of both the target and source slots are themselves are objects. (That's a very broad-strokes description!)
But I find your question also puzzling, because it suggests that "extends" is a function that, when available, gets called automatically by the interpreter in certain situations, just like, e.g., valueOf or toString. If this is the case then I'm even more mystified than before, because I've never heard of such a thing. (FWIW, Flanagan doesn't even *mention* extend.)
Kynn
P.S. I really need to get myself an authoritative reference on JavaScript... I thought that Flanagan's book was it, but just today I've run into a few topics (such as the const keyword) that Flanagan doesn't even *mention*. I'm wondering if "extend" will be another such blind spot...
-- NOTE: In my address everything before the first period is backwards; and the last period, and everything after it, should be discarded.
kj <so...@987jk.com.invalid> writes: > My book (Flanagan's JavaScript: The Definitive Guide, 5th ed.) > implies on page 111 that the following two constructs are equivalent:
> ( x.constructor == Foo )
> and
> ( x instanceof Foo )
They're not. For one thing, obj.constructor does the wrong thing when the constructor has a prototype assigned to it, since the constructor is actually determined by the prototype.
function Super() {} function Sub() {} Sub.prototype = new Super(); // note: this is wrong, but since it // but everybody does it and it works. // more or less. // unless you actually want to read the // the constructor later
var sub = new Sub(); // like here, sub.constructor == Super!
also, instanceof checks the full prototype chain, while obj.constructor can only be a single value, so it's useless for inherited objects.
> The author states that the instanceof operator computes its result > by examining the value of its first argument's the constructor > property.
> However, I've recently ran into a situation that contradicts this.
As shown above, you're right. One of the problems is that you can't access an object's prototype directly, you apparently have to use obj.constructor.prototype, *but* obj.constructor is read from the objects's prototype, which is why replacing a constructor's prototype outright leads to issues. My current strategy in those cases where I need access to the constructor directly is to merge properties into the existing prototype instead.
>kj <so...@987jk.com.invalid> writes: >> My book (Flanagan's JavaScript: The Definitive Guide, 5th ed.) >> implies on page 111 that the following two constructs are equivalent:
>> ( x.constructor == Foo )
>> and
>> ( x instanceof Foo ) >They're not. For one thing, obj.constructor does the wrong thing when >the constructor has a prototype assigned to it, since the constructor is >actually determined by the prototype. >function Super() {} >function Sub() {} >Sub.prototype = new Super(); // note: this is wrong, but since it > // but everybody does it and it works. > // more or less. > // unless you actually want to read the > // the constructor later >var sub = new Sub(); // like here, sub.constructor == Super! >alert(sub.constructor == Sub); // false >alert(sub.constructor == Super); // true >alert(sub instanceof Sub); // true >alert(sub instanceof Super); // true >also, instanceof checks the full prototype chain, while obj.constructor >can only be a single value, so it's useless for inherited objects. >> The author states that the instanceof operator computes its result >> by examining the value of its first argument's the constructor >> property.
>> However, I've recently ran into a situation that contradicts this. >As shown above, you're right. One of the problems is that you can't >access an object's prototype directly, you apparently have to use >obj.constructor.prototype, *but* obj.constructor is read from the >objects's prototype, which is why replacing a constructor's prototype >outright leads to issues. My current strategy in those cases where I >need access to the constructor directly is to merge properties into the >existing prototype instead.
Thank you very much! Your post (and liamgegan's) finally clarified the matter for me. Indeed, in the jQuery source, I see that jQuery.prototype gets assigned an anonymous object...
kynn
-- NOTE: In my address everything before the first period is backwards; and the last period, and everything after it, should be discarded.
> In <7a310b71-b65d-42b6-9bd0-fee6d18ba...@e10g2000prf.googlegroups.com> "liamge...@gmail.com" <liamge...@gmail.com> writes:
> >I know that there are difference in the way that instanceof is > >determined vs. x.constructor. In this instance it sounds like it's an > >issue with the way that JQuery handles it's extends functionality. Not > >having used JQuery a great deal, could you shed some light on the way > >that JQuery extends?
> That went over my head! :-) But I'll do my best...
> The jQuery object does have an extend method, if that's what you're > asking. It can be invoked in a few ways, but probably the most > general one is something like
> If bool is false, extend copies values from obj1, obj2, obj3, etc. > into the corresponding slots in target. If bool is true, instead > of copying it extends the slots when the the contents of both the > target and source slots are themselves are objects. (That's a very > broad-strokes description!)
> But I find your question also puzzling, because it suggests that > "extends" is a function that, when available, gets called automatically > by the interpreter in certain situations, just like, e.g., valueOf > or toString. If this is the case then I'm even more mystified than > before, because I've never heard of such a thing. (FWIW, Flanagan > doesn't even *mention* extend.)
> Kynn
> P.S. I really need to get myself an authoritative reference on > JavaScript... I thought that Flanagan's book was it, but just > today I've run into a few topics (such as the const keyword) that > Flanagan doesn't even *mention*. I'm wondering if "extend" will > be another such blind spot...
> -- > NOTE: In my address everything before the first period is backwards; > and the last period, and everything after it, should be discarded.
Sorry, I didn't mean to confuse :D
Extends functionality is unavailable in Javascript, but is a fundamental feature of other OOP languages (including AS 2+ [also ECMA]). In Javascript as in AS1, Extends functionality needed to be simulated in one of 3 ways, each with advantages of their own (but also with many and varied problems): a) copy all methods from subclass into superclass and provided an implemented constructor. I always hated this way as it's more implementation than an extension. b) sub.__proto__ = super.prototype; This seems to be the most correct type to me, but can easily break down expected behaviour in the sub/ super relationship if you don't understand it properley; c) sub.prototype = new Super(); Probably the most used method, but the class instanciation always seemed superfluous to me.
Joost Diepenmaat wrote: > kj <so...@987jk.com.invalid> writes: >> My book (Flanagan's JavaScript: The Definitive Guide, 5th ed.) >> implies on page 111 that the following two constructs are equivalent:
>> ( x.constructor == Foo )
>> and
>> ( x instanceof Foo )
> They're not.
True. I wonder how long it will take until everybody recognizes that Flanagan actually has no clue what he is writing about.
> For one thing, obj.constructor does the wrong thing when the constructor > has a prototype assigned to it, since the constructor is actually determined > by the prototype.
The constructor is the Function object that was used to create the object. It has a `prototype' property implicitly. It is not that this property is assigned a value that makes the `constructor' property of the created object useless, but when this value is not an object that provides a user-defined `constructor' property to refer to the constructor.
> function Super() {} > function Sub() {} > Sub.prototype = new Super(); // note: this is wrong, but since it > // but everybody does it and it works.
Not everybody does it, as it does not work, because it is wrong. This statement does not add Super.prototype to the prototype chain of Sub objects; it adds a newly created Super object there:
new Sub() --> Sub.prototype --> new Super() --> Super.prototype --> ... --> Object.prototype
So there is no real prototype-based inheritance anymore as any property value that is defined for Super objects only in their constructor is inherited from that object through the prototype chain, even though Super.prototype does not need to have that property or provides a different default value for it.
One way to do it properly is this oft-recommended approach:
function extend(P) { function Dummy() {} Dummy.prototype = P; return new Dummy(); }
Sub.prototype = extend(Super.prototype);
The resulting prototype chain is then
new Sub() --> Sub.prototype === new Dummy() --> Dummy.prototype === Super.prototype --> ... --> Object.prototype
as it should be. (A prototype object is inserted into the prototype chain.)
> // more or less.
It fails whenever prototype properties are involved, for example. Search the newsgroup for details.
PointedEars -- Prototype.js was written by people who don't know javascript for people who don't know javascript. People who don't know javascript are not the best source of advice on designing systems that use javascript. -- Richard Cornford, cljs, <f806at$ail$1$8300d...@news.demon.co.uk>
Thomas 'PointedEars' Lahn <PointedE...@web.de> writes:
> Joost Diepenmaat wrote: >> kj <so...@987jk.com.invalid> writes: >>> My book (Flanagan's JavaScript: The Definitive Guide, 5th ed.) >>> implies on page 111 that the following two constructs are equivalent:
>>> ( x.constructor == Foo )
>>> and
>>> ( x instanceof Foo )
>> They're not.
> True. I wonder how long it will take until everybody recognizes that > Flanagan actually has no clue what he is writing about.
For some reason /nobody/ I've read gets OO javascript right except Crockford. And I just looked up that page in Flanagan, and he *does* just outright say instanceof checks the constructor property. He should know better.
>> For one thing, obj.constructor does the wrong thing when the constructor >> has a prototype assigned to it, since the constructor is actually determined >> by the prototype.
> The constructor is the Function object that was used to create the object. > It has a `prototype' property implicitly. It is not that this property is > assigned a value that makes the `constructor' property of the created object > useless, but when this value is not an object that provides a user-defined > `constructor' property to refer to the constructor.
Yes, you're right about that. I could have stated that more clearly.
>> function Super() {} >> function Sub() {} >> Sub.prototype = new Super(); // note: this is wrong, but since it >> // but everybody does it and it works.
> Not everybody does it, as it does not work, because it is wrong.This > statement does not add Super.prototype to the prototype chain of Sub > objects;
Of course it does. Just confusingly. See your diagram directly below.
> it adds a newly created Super object there:
> new Sub() --> Sub.prototype --> new Super() --> Super.prototype --> ... > --> Object.prototype
For example:
function Super() {} Super.prototype.thingy=42;
function Sub() {} Sub.prototype = new Super();
alert((new Sub()).thingy); // 42.
> So there is no real prototype-based inheritance anymore as any property > value that is defined for Super objects only in their constructor is > inherited from that object through the prototype chain, even though > Super.prototype does not need to have that property or provides a different > default value for it.
So? Super() does not add any properties, and even if it did, that won't make it wrong. It's just that constructors confuse matters.
> One way to do it properly is this oft-recommended approach:
> function extend(P) > { > function Dummy() {} > Dummy.prototype = P; > return new Dummy(); > }
> Sub.prototype = extend(Super.prototype);
> The resulting prototype chain is then
> new Sub() --> Sub.prototype === new Dummy() --> Dummy.prototype === > Super.prototype --> ... --> Object.prototype
What? Just. No. That's just even *more* confusing. Why not do this if you want real prototyping:
var SubProto = {}; var SuperProto = extend(SubProto); var super = extend(sub);
and just forget about "new constructor()" altogether and use extend() to create *all* objects. Constructors are an ugly, ugly hack in JavaScript anyway.
Joost Diepenmaat wrote: > Thomas 'PointedEars' Lahn <PointedE...@web.de> writes: >> Joost Diepenmaat wrote: >>> kj <so...@987jk.com.invalid> writes: >>>> My book (Flanagan's JavaScript: The Definitive Guide, 5th ed.) >>>> implies on page 111 that the following two constructs are equivalent:
>>>> ( x.constructor == Foo )
>>>> and
>>>> ( x instanceof Foo ) >>> They're not. >> True. I wonder how long it will take until everybody recognizes that >> Flanagan actually has no clue what he is writing about.
> For some reason /nobody/ I've read gets OO javascript right except > Crockford. [...]
Including you? ;-)
>>> function Super() {} >>> function Sub() {} >>> Sub.prototype = new Super(); // note: this is wrong, but since it >>> // but everybody does it and it works. >> Not everybody does it, as it does not work, because it is wrong.This >> statement does not add Super.prototype to the prototype chain of Sub >> objects;
> Of course it does. Just confusingly. See your diagram directly below.
OK, it does add Super.prototype, but it does not add it in the proper way.
>> it adds a newly created Super object there:
>> new Sub() --> Sub.prototype --> new Super() --> Super.prototype --> ... >> --> Object.prototype
> For example:
> function Super() {} > Super.prototype.thingy=42;
> function Sub() {} > Sub.prototype = new Super();
> alert((new Sub()).thingy); // 42.
You miss the point. For example:
function Super() {} Super.prototype.items = [];
function Sub() {} Sub.prototype = new Super();
var sub1 = new Sub(); var sub2 = new Sub(); sub1.items.push(42);
// yields [42], instead of [] as it should sub2.items
Lasse Reichstein Nielsen already pointed that out when this issue first (or at least most intensively) came up here. You really should increase the range of your research.
>> So there is no real prototype-based inheritance anymore as any property >> value that is defined for Super objects only in their constructor is >> inherited from that object through the prototype chain, even though >> Super.prototype does not need to have that property or provides a different >> default value for it.
> So? Super() does not add any properties, and even if it did, that won't > make it wrong.
Yes, it would. The object inherited from would not be Super.prototype, but a Super object (no pun intended):
function Super() { this.foo = "bar"; }
function Sub() {} Sub.prototype = new Super();
var sub1 = new Sub(); Super.prototype.foo = 42;
// yields "bar", instead of 42 as it should sub1.foo
>> One way to do it properly is this oft-recommended approach:
>> function extend(P) >> { >> function Dummy() {} >> Dummy.prototype = P; >> return new Dummy(); >> }
>> Sub.prototype = extend(Super.prototype);
>> The resulting prototype chain is then
>> new Sub() --> Sub.prototype === new Dummy() --> Dummy.prototype === >> Super.prototype --> ... --> Object.prototype
> What? Just. No. That's just even *more* confusing.
No, it is has been proven a correct approach, if not *the* correct one. Again, you should search the newsgroup.
[imported correction from <8763xep3ay....@zeekat.nl>]
> Why not do this if you want real prototyping:
> var SubProto = {}; > var SuperProto = extend(SubProto); > var super = extend(SuperProto);
Nonsense. User-defined objects should inherit from prototype (Object) objects, not from constructor (Function) objects.
It is possible to pass the constructor instead of the prototype object, but extend() can be renamed clone() and the necessary hard-coding of the prototype property in it would prevent this code reuse. Besides, passing the prototype object explicitly shows the caller what is going to happen; I consider that a Good Thing.
> and just forget about "new constructor()" altogether and use extend() to > create *all* objects. Constructors are an ugly, ugly hack in JavaScript > anyway.
I don't think so.
PointedEars -- Prototype.js was written by people who don't know javascript for people who don't know javascript. People who don't know javascript are not the best source of advice on designing systems that use javascript. -- Richard Cornford, cljs, <f806at$ail$1$8300d...@news.demon.co.uk>
Thomas 'PointedEars' Lahn wrote: > [imported correction from <8763xep3ay....@zeekat.nl>] >> Why not do this if you want real prototyping:
>> var SubProto = {}; >> var SuperProto = extend(SubProto); >> var super = extend(SuperProto);
`super' is a reserved word.
> Nonsense. User-defined objects should inherit from prototype (Object) > objects, not from constructor (Function) objects. > [...]
Please ignore that, I was overlooking that you are using Object objects already.
>> and just forget about "new constructor()" altogether and use extend() to >> create *all* objects. [...]
While the identifiers are confusing and even misleading, it certainly is an interesting idea: One Object object would inherit from the other, indeed. However, it looks as if there was a bug in it and I just don't see it yet.
In comp.lang.javascript message <fnj3ag$jk...@reader2.panix.com>, Sun, 27 Jan 2008 23:15:28, kj <so...@987jk.com.invalid> posted:
>P.S. I really need to get myself an authoritative reference on >JavaScript...
So get ISO/IEC 16262, free as a PDF.
> I thought that Flanagan's book was it, but just >today I've run into a few topics (such as the const keyword) that >Flanagan doesn't even *mention*. I'm wondering if "extend" will >be another such blind spot...
Remember that a script engine author needs to know everything in the current and the imminent standards, and should also know what other script engines actually do. For that, ordinary books cannot be expected to suffice.
But a page author needs to know only those standards with which current and recent script engines are compliant, and what the common browsers actually do; if he knows anything else, he must keep the two sets of knowledge quite separate in his mind.
Thomas 'PointedEars' Lahn <PointedE...@web.de> writes:
> You miss the point. For example:
> function Super() {} > Super.prototype.items = [];
> function Sub() {} > Sub.prototype = new Super();
> var sub1 = new Sub(); > var sub2 = new Sub(); > sub1.items.push(42);
> // yields [42], instead of [] as it should > sub2.items
That's expected. Prototypes aren't templates, they're objects in their own right, and sharing a prototype, which is exactly what constructors do to their generated objects, means you're sharing the prototype's properties until you override them by setting them in the super object. But you know that.
>> It's just that constructors confuse matters.
> I don't agree.
I belief they do: constructors are just way of setting prototypes and properties but they look way too much like classes / class-based constructors.
Joost Diepenmaat <jo...@zeekat.nl> writes: > Thomas 'PointedEars' Lahn <PointedE...@web.de> writes:
>> You miss the point. For example:
>> function Super() {} >> Super.prototype.items = [];
>> function Sub() {} >> Sub.prototype = new Super();
>> var sub1 = new Sub(); >> var sub2 = new Sub(); >> sub1.items.push(42);
>> // yields [42], instead of [] as it should >> sub2.items
> That's expected. Prototypes aren't templates, they're objects in their > own right, and sharing a prototype, which is exactly what constructors > do to their generated objects, means you're sharing the prototype's > properties until you override them by setting them in the super > object. ^^^^^
Joost Diepenmaat wrote: > Thomas 'PointedEars' Lahn <PointedE...@web.de> writes: >> You miss the point. For example:
>> function Super() {} >> Super.prototype.items = [];
>> function Sub() {} >> Sub.prototype = new Super();
>> var sub1 = new Sub(); >> var sub2 = new Sub(); >> sub1.items.push(42);
>> // yields [42], instead of [] as it should >> sub2.items
> That's expected.
No, it is _not_ expected at all that two objects derived from the same prototype share their property *values*. The very point about objects is that they have identity, that they *differ* from each other.
> Prototypes aren't templates, they're objects in their own right,
I'm afraid you are in error here. Prototypes are objects in their own right, but the term "prototype", translatable at least into all Indo-European languages, including Nederlands if I may say so, has the meaning of "template". In engineering, a working prototype is the first thing you need to make a series of machines with similar functionality and properties. Note that since the words are not being used in the OOP sense here, the connection is most obvious.
> Joost Diepenmaat wrote: >> Thomas 'PointedEars' Lahn <PointedE...@web.de> writes: >>> You miss the point. For example:
>>> function Super() {} >>> Super.prototype.items = [];
>>> function Sub() {} >>> Sub.prototype = new Super();
>>> var sub1 = new Sub(); >>> var sub2 = new Sub(); >>> sub1.items.push(42);
>>> // yields [42], instead of [] as it should >>> sub2.items
>> That's expected.
> No, it is _not_ expected at all that two objects derived from the same > prototype share their property *values*. The very point about objects > is that they have identity, that they *differ* from each other.
Javascript does not clone from a prototype, it just links the new object to its prototype and does property lookup via the prototype chain. If you want cloning of certain properties (and you usually don't want to clone ALL properties) you have to make it happen yourself.
Provided you know that, nothing about the above code should be confusing. Well except that it becomes very unclear why you'd need constructors at all.
>> Prototypes aren't templates, they're objects in their own right,
> I'm afraid you are in error here. Prototypes are objects in their > own right, but the term "prototype", translatable at least into all > Indo-European languages, including Nederlands if I may say so, has > the meaning of "template". In engineering, a working prototype is > the first thing you need to make a series of machines with similar > functionality and properties. Note that since the words are not > being used in the OOP sense here, the connection is most obvious.
I thought this was a JavaScript group. The meaning of the word in JavaScript is what matters to me.
Joost Diepenmaat wrote: > Thomas 'PointedEars' Lahn <PointedE...@web.de> writes: >> Joost Diepenmaat wrote: >>> Thomas 'PointedEars' Lahn <PointedE...@web.de> writes: >>>> You miss the point. For example:
>>>> function Super() {} >>>> Super.prototype.items = [];
>>>> function Sub() {} >>>> Sub.prototype = new Super();
>>>> var sub1 = new Sub(); >>>> var sub2 = new Sub(); >>>> sub1.items.push(42);
>>>> // yields [42], instead of [] as it should >>>> sub2.items >>> That's expected. >> No, it is _not_ expected at all that two objects derived from the same >> prototype share their property *values*. The very point about objects >> is that they have identity, that they *differ* from each other.
> Javascript does not clone from a prototype, it just links the new object > to its prototype and does property lookup via the prototype chain. If > you want cloning of certain properties (and you usually don't want to > clone ALL properties) you have to make it happen yourself.
You are not making sense. Don't you see that your *wrong* assignment can make objects share not only their properties, but also their property values, i.e. clones them?
> Provided you know that, nothing about the above code should be > confusing. Well except that it becomes very unclear why you'd need > constructors at all.
Disagreed.
>>> Prototypes aren't templates, they're objects in their own right, >> I'm afraid you are in error here. Prototypes are objects in their >> own right, but the term "prototype", translatable at least into all >> Indo-European languages, including Nederlands if I may say so, has >> the meaning of "template". In engineering, a working prototype is >> the first thing you need to make a series of machines with similar >> functionality and properties. Note that since the words are not >> being used in the OOP sense here, the connection is most obvious.
> I thought this was a JavaScript group. The meaning of the word in > JavaScript is what matters to me.
The meaning of the word in software engineering, including programming in ECMAScript implementations, is clearly derived from the meaning of the word in general engineering. It is simply unreasonable to deny that.
Thanks, I was looking for that. However, you should consider that the increased runtime efficiency gained by declaring the Dummy() constructor only once is mitigated by the reduced memory efficiency caused by the continued allocation of memory due to the closure. And since there are more issues with closures than without them, I would avoid them here.
PointedEars -- realism: HTML 4.01 Strict evangelism: XHTML 1.0 Strict madness: XHTML 1.1 as application/xhtml+xml -- Bjoern Hoehrmann
Thomas 'PointedEars' Lahn <PointedE...@web.de> writes:
>> Javascript does not clone from a prototype, it just links the new object >> to its prototype and does property lookup via the prototype chain. If >> you want cloning of certain properties (and you usually don't want to >> clone ALL properties) you have to make it happen yourself.
> You are not making sense. Don't you see that your *wrong* assignment can > make objects share not only their properties, but also their property > values, i.e. clones them?
Linking to a prototype does not clone anything. That's the reason the properties are shared. If they were cloned they wouldn't be shared.
>> Provided you know that, nothing about the above code should be >> confusing. Well except that it becomes very unclear why you'd need >> constructors at all.
> Disagreed.
*shrug*
>> I thought this was a JavaScript group. The meaning of the word in >> JavaScript is what matters to me.
> The meaning of the word in software engineering, including programming in > ECMAScript implementations, is clearly derived from the meaning of the word > in general engineering. It is simply unreasonable to deny that.
Thomas 'PointedEars' Lahn <PointedE...@web.de> writes:
> Thanks, I was looking for that. However, you should consider that the > increased runtime efficiency gained by declaring the Dummy() constructor > only once is mitigated by the reduced memory efficiency caused by the > continued allocation of memory due to the closure. And since there are > more issues with closures than without them, I would avoid them here.
function Dummy(){} function extend(proto) { Dummy.prototype=proto; return new Dummy();
}
No closure. Though I would be amazed if it would have any significant impact on memory use.
Joost Diepenmaat wrote: > Thomas 'PointedEars' Lahn <PointedE...@web.de> writes: >> Thanks, I was looking for that. However, you should consider that the >> increased runtime efficiency gained by declaring the Dummy() constructor >> only once is mitigated by the reduced memory efficiency caused by the >> continued allocation of memory due to the closure. And since there are >> more issues with closures than without them, I would avoid them here.
> function Dummy(){} ^^^^^ > function extend(proto) { > Dummy.prototype=proto; ^^^^^ > return new Dummy(); > }
> No closure. [...]
I think there is one. `Dummy' was declared in the definition context of `extend' that `extend' reproduces when it is called; that is how a closure is defined.
PointedEars -- Use any version of Microsoft Frontpage to create your site. (This won't prevent people from viewing your source, but no one will want to steal it.) -- from <http://www.vortex-webdesign.com/help/hidesource.htm>
> Joost Diepenmaat wrote: >> Thomas 'PointedEars' Lahn <PointedE...@web.de> writes: >>> Thanks, I was looking for that. However, you should consider that the >>> increased runtime efficiency gained by declaring the Dummy() constructor >>> only once is mitigated by the reduced memory efficiency caused by the >>> continued allocation of memory due to the closure. And since there are >>> more issues with closures than without them, I would avoid them here.
>> function Dummy(){} > ^^^^^ >> function extend(proto) { >> Dummy.prototype=proto; > ^^^^^ >> return new Dummy(); >> }
>> No closure. [...]
> I think there is one. `Dummy' was declared in the definition > context of `extend' that `extend' reproduces when it is called; > that is how a closure is defined.
If you're defining closures like that, every function that calls another function, or accesses any other global property would be a closure:
function a() { alert() } function b() { a(); }
My informal definition is that a closure is a function that keeps references to objects that are defined in an outer lexical scope. Dummy here is just a property of the global object, not a lexical variable.
Joost Diepenmaat wrote: > Thomas 'PointedEars' Lahn <PointedE...@web.de> writes: >>> Javascript does not clone from a prototype, it just links the new object >>> to its prototype and does property lookup via the prototype chain. If >>> you want cloning of certain properties (and you usually don't want to >>> clone ALL properties) you have to make it happen yourself. >> You are not making sense. Don't you see that your *wrong* assignment can >> make objects share not only their properties, but also their property >> values, i.e. clones them?
> Linking to a prototype does not clone anything. That's the reason the > properties are shared. If they were cloned they wouldn't be shared.
That would define how you define "clone". Suffice it to say that two objects implicitly share their property values this way when derived from the same prototype object is definitely counter-intuitive. It is the direct result of the wrong application of prototype-based inheritance in ECMAScript implementations.
>>> I thought this was a JavaScript group. The meaning of the word in >>> JavaScript is what matters to me. >> The meaning of the word in software engineering, including programming in >> ECMAScript implementations, is clearly derived from the meaning of the word >> in general engineering. It is simply unreasonable to deny that.
> I didn't deny that. Stick to the subject.
You must be kidding.
EOD
PointedEars -- realism: HTML 4.01 Strict evangelism: XHTML 1.0 Strict madness: XHTML 1.1 as application/xhtml+xml -- Bjoern Hoehrmann
Joost Diepenmaat wrote: > Thomas 'PointedEars' Lahn <PointedE...@web.de> writes: >> Joost Diepenmaat wrote: >>> function Dummy(){} >> ^^^^^ >>> function extend(proto) { >>> Dummy.prototype=proto; >> ^^^^^ >>> return new Dummy(); >>> }
>>> No closure. [...] >> I think there is one. `Dummy' was declared in the definition >> context of `extend' that `extend' reproduces when it is called; >> that is how a closure is defined.
> If you're defining closures like that,
It is not my definition.
> every function that calls another function,
Not every function. It depends on where the other function was defined.
> or accesses any other global property would be a closure: > [...]
That is correct. Probably that is why Flanagan made his oversimplifying false statement.
> My informal definition is that a closure is a function that keeps > references to objects that are defined in an outer lexical scope. Dummy > here is just a property of the global object, not a lexical variable.
Note that functions are first-class objects in ECMAScript implementations.
PointedEars -- realism: HTML 4.01 Strict evangelism: XHTML 1.0 Strict madness: XHTML 1.1 as application/xhtml+xml -- Bjoern Hoehrmann