Objects comparaison ?

J

John G Harris

Object.equals = function(obj1, obj2) {
if (typeof obj1 != "object" || obj1 == null
|| typeof obj2 != "object" || obj2 == null)
<snip>

Attaching a global function (note it has two parameters) to Object is a
very bad idea.

If you want to emulate a namespace you should use a dedicated namespace
object.

John
 
M

Michael Haufe (TNO)

On Sun, 16 Oct 2011 at 21:59:39, in comp.lang.javascript, Thomas

'PointedEars' Lahn wrote:



  <snip>

Attaching a global function (note it has two parameters) to Object is a
very bad idea.

If you want to emulate a namespace you should use a dedicated namespace
object.

I'm pretty certain it was just an example used to express the idea...
 
A

Andreas Bergmaier

D

dhtml

Why that? I'd say it just belongs to there as other Object methods (like
keys() oder defineProperty(), seehttps://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/...).
It is a problem if ES.Next defines Object.equals because now there are
two `Object.equals` methods that work differently. As a matter of
style, I prefer to clearly separate my own functions from that which
is defined from the script engine and host environment.
 
T

Thomas 'PointedEars' Lahn

John said:
<snip>

Attaching a global function (note it has two parameters) to Object is a
very bad idea.

Nonsense. You have to differentiate between `Object' and
`Object.prototype'.

However, this was just a proof-of-concept. Because someone at the ECMA-262
WG could get the idea that an Object.equals() etc. could come in handy at
some time, in a real implementation I would use my own namespace, unless the
method definition serves as a fallback for a specified method not being
implemented (for example, Object.defineProperty()). One of the next JSX
revisions will reflect that.
If you want to emulate a namespace you should use a dedicated namespace
object.

I am not emulating a namespace here, though.


PointedEars
 
T

Thomas 'PointedEars' Lahn

Andreas said:
Why that? I'd say it just belongs to there as other Object methods (like
keys() oder defineProperty(), see
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object#Methods).

The risk involved is that Object.equals() could be specified as a built-in
later, maybe differently, and implemented. It might or might not be
specified as read-only then, and if not, this would overwrite the built-in
definition.

Once specified and not implemented, however, such properties should be safe
to be added like that, so that the efficiency of the native code can be
leveraged without having to change the calling code. It requires the user-
defined fallback to follow the Specification literally, though.
And what do you mean with "it has parameters"? Attaching a function
without parameters, or attaching a non-function property would be OK?

He is confusing this with Object.prototype.equals(obj1, obj2), which would
be a rather bad idea indeed, for two reasons:

First, it would show up in for-in iteration as it would be enumerable (and
it remains to be seen how widely Object.defineProperty() is implemented, so
that this can be prevented).

Second, the conflict between the `this' value and one of the arguments needs
to be resolved: Which value refers to the object being compared against? (I
would opt for the second argument to override the default `this' value, so
that it can be optional. Cf. Array.prototype.filter(), e.g.)


PointedEars
 
J

John G Harris

Andreas Bergmaier wrote:


He is confusing this with Object.prototype.equals(obj1, obj2),

It's not me that's confused. You attached the function to Object, a
constructor. That is what I was commenting on.

which would
be a rather bad idea indeed, for two reasons:

First, it would show up in for-in iteration as it would be enumerable (and
it remains to be seen how widely Object.defineProperty() is implemented, so
that this can be prevented).

Second, the conflict between the `this' value and one of the arguments needs
to be resolved: Which value refers to the object being compared against?
<snip>

There is no conflict. Which values are to be compared is resolved by the
function's specification. You do have one, don't you? From the displayed
code it appears to be obj1 and obj2; the this value is not used.

John
 
J

John G Harris

Nonsense.

Object is a constructor. Its job is to *construct*, not to act like a
Christmas tree with shiny ornaments dangling from it.

You have to differentiate between `Object' and
`Object.prototype'.

Very true. Use of Object is confusing. In a bug hunt during a major
panic someone could misunderstand, insert '.prototype' in a hurry, then
not test it, then forget it.

Note that confusion has already occurred.

Using the Math object would be better, though there is still the risk of
clashing with a future version of the language or with someone else's
code.

However, this was just a proof-of-concept.

That's no excuse for showing bad habits to beginners.

Because someone at the ECMA-262
WG could get the idea that an Object.equals() etc.

Are you getting confused now?


<snip>

John
 
J

Jukka Lahtinen

dhtml said:
Java `Object.equals` does nothing more than use Java's == which is
analagous to JavaScript's ===.

WRONG!
Java's == operator tests whether the expressions on each side point to
the same object, while the equals method tests whether the contents of
two objects are same.
Thus in java, "foo == bar" may return false even when "foo.equals(bar)"
returns true.
 
T

Thomas 'PointedEars' Lahn

John said:
Object is a constructor. Its job is to *construct*, not to act like a
Christmas tree with shiny ornaments dangling from it.

Obviously you have no clue about this programming language.


PointedEars
 
T

Thomas 'PointedEars' Lahn

John said:
It's not me that's confused. You attached the function to Object, a
constructor. That is what I was commenting on.

In order to save yourself from further embarassment, you really want to have
at least a look at the ECMAScript Language Specification, Edition 5 Final,
before further commenting on the programming that is on-topic here.
<snip>

There is no conflict. Which values are to be compared is resolved by the
function's specification. You do have one, don't you? From the displayed
code it appears to be obj1 and obj2; the this value is not used.

I was talking about the other way to implement this,
Object.prototype.equals(), in that paragraph, as can be seen further above.
Assuming it would be implemented that way,

Object.prototype.equals = function(obj1, obj2) {
…
};

then Object instances (and all objects that inherit from [the object
referred to by] Object.prototype through their prototype chain) would
inherit that method (which is part of why that is not a good idea at the
moment). Then it would be possible to call

({}).equals(foo, bar);

and one would need to decide in one's implementation what value acts as the
`this' value in the equals() code, if any: either that of `foo', or that of
`bar'. (My recommendation stands that it should be that of `bar'.)

Such considerations do not have to be made if you have a "static" method
that is not inherited by other objects implicitly, as in the first approach.
Those methods are not supposed to be transferred to other objects.


PointedEars
 
S

Scott Sauyet

John said:
Object is a constructor. Its job is to *construct*, not to act like a
Christmas tree with shiny ornaments dangling from it.

So, do you also object to Object.create, Date.parse, Number.NaN,
String.fromCharCode and everywhere else the language associates
'static' properties with constructor functions?

-- Scott
 
M

Michael Haufe (TNO)

So, do you also object to Object.create, Date.parse, Number.NaN,
String.fromCharCode and everywhere else the language associates
'static' properties with constructor functions?

Yes
 
M

Michael Haufe (TNO)


More productively, and for the sake of argument only:

String.fromCharCode -> 7.fromCharCode()
Date.parse("July 28, 2005") -> "July 28, 2005".parseDate()
//Number.NaN makes as much sense to me as Number.7
Number.NaN -> NaN
Object.create(o) -> o.new

etc...
 
S

Scott Sauyet

Michael Haufe (TNO) said:
Scott said:
John G Harris wrote:
So, do you also object to Object.create, Date.parse, Number.NaN,
String.fromCharCode and everywhere else the language associates
'static' properties with constructor functions?

[F]or the sake of argument only:

Interesting. Can you explain why you prefer these formulations? I
have no problem at all with using these objects as quasi-namespaces
for related global functionality.
String.fromCharCode    ->  7.fromCharCode()

Okay, except that this functions takes an arbitrary number of
parameters. How would you handle that?

Date.parse("July 28, 2005") ->  "July 28, 2005".parseDate()

This could work, but what does this have to do String instances?
Should Strings also have parseRegex, parseBoolean, parseJsonObject,
and other similar functions. If so, why? What does this have to do
with Strings?

//Number.NaN makes as much sense to me as Number.7
Number.NaN  ->  NaN

Would you also make global Number.NEGATIVE_INFINITY, Number.MAX_VALUE,
and the like? To what end? I think there is already far too much in
the global namespace.

Object.create(o)   ->  o.new

This I can almost buy, implemented with code resembling the following:

Object.prototype.new = function() {
// create new object and copy over all properties of `this`
}

But I don't see the harm in the 'Object.create' syntax. What's the
objection?

-- Scott
 
J

John G Harris

So, do you also object to Object.create, Date.parse, Number.NaN,
String.fromCharCode and everywhere else the language associates
'static' properties with constructor functions?

No-one says ECMAScript is perfect :) In fact, someone wrote a whole
book saying it isn't.

Also, notice that the functions dangling from Object apply to only one
object and require special privileged access to the insides of objects.
A function that can be used to compare two strings is not appropriate.

Have you considered what you would do if a 'class' has two constructors?
E.g Thing and ThingClone.

John
 
J

John G Harris

In order to save yourself from further embarassment, you really want to have
at least a look at the ECMAScript Language Specification, Edition 5 Final,
before further commenting on the programming that is on-topic here.

You really do need to learn to provide a reasoned explanation instead of
abusive hot air.

I was talking about the other way to implement this,
Object.prototype.equals(), in that paragraph, as can be seen further above.
Assuming it would be implemented that way,

Object.prototype.equals = function(obj1, obj2) {
…
};
<snip>

What a bloody awful thing to do. Are you crazy? A method shouldn't
ignore the 'this' value: a.equals(...) should act on 'a' except when 'a'
is explicitly emulating a namespace.

The central tenet of OO is that you say to an object "you do it; I don't
know how to, nor do I care". Hence the expectation that a.b does
something to or with 'a'.


John
 
S

Scott Sauyet

John said:
No-one says ECMAScript is perfect :) In fact, someone wrote a whole
book saying it isn't.

Also, notice that the functions dangling from Object apply to only one
object and require special privileged access to the insides of objects.
A function that can be used to compare two strings is not appropriate.

So is your concern only with Object as the root of the object
hierarchy, or does your objection apply to all constructor functions?
Date.parse doesn't accept a Date, only a String. String.fromCharCode
accepts a number of integers.

I use this pattern extensively, and wonder if you have an objection to
it, and if so, why:

var MyConstructor = function() { /* ... */ };
MyConstructor.prototype = { /* ... */ }
MyConstructor.staticFunc1 = function() { /* ... */ };

Have you considered what you would do if a 'class' has two constructors?
E.g Thing and ThingClone.

I don't generally think of these static functions as operating
specifically on single instances that were constructed from the
function, so I don't think of it as an issue. But just out of
curiosity, how would you accomplish this multiple constructor
scenario?

-- Scott
 
A

Antony Scriven

More productively, and for the sake of argument only:

Well, since we're already off-topic :)
String.fromCharCode -> 7.fromCharCode()

And neither of those can be usefully passed to map(). :-(
Date.parse("July 28, 2005") -> "July 28, 2005".parseDate()

I would have thought that knowing how to parse a date is the
domain of the Date object.
//Number.NaN makes as much sense to me as Number.7
Number.NaN -> NaN

Or Math.PI? --Antony
 
A

Antony Scriven

[...]

I use this pattern extensively, and wonder if you have an
objection to it, and if so, why:

var MyConstructor = function() { /* ... */ };
MyConstructor.prototype = { /* ... */ }
MyConstructor.staticFunc1 = function() { /* ... */ };

No objections (though I conceptually prefer
Object.create()). But I don't think you should call
a regular function 'staticFunc1': I think it will confuse
newcomers familiar with class-based languages. --Antony
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top