[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.javascript

What technique I use in functions?

Angel Rodriguez

6/14/2015 9:39:00 PM

I'm working on a project, and I am defining my style of programming functions in javascript. With what I have studied, I have seen three methods for working with functions and I would like to know what kind of method you would use considering scalability, performance, maintenance, etc.

// METHOD 1. Only Prototyping the Methods

function a() {
this.mySecret = 5;
this.myOtherSecret = 7;
}
a.prototype.someThingA = function() {
return this.mySecret + this.myOtherSecret;
}
a.prototype.someThingElseA = function() {
return 100 + this.someThingA();
}

// METHOD 2. Prototyping and Encapsulating the Methods

function b() {
this.mySecret = 5;
this.myOtherSecret = 7;
}
(function() {
this.someThingB = function() {
return this.mySecret + this.myOtherSecret;
}
this.someThingElseB = function() {
return 100 + this.someThingB();
}
}).call(b.prototype);

// METHOD 3. Using an Object !

var myObj = {

mySecret: 5,
myOtherSecret: 7,
someThing: function(){
return this.mySecret + this.myOtherSecret;
},
someThingElse: function(){
return 100 + this.someThing();
}
};

// Invoking the functions

var methodA = new a();
console.log( methodA.someThingElseA() );

var methodB = new b();
console.log( methodB.someThingElseB() );

console.log(myObj.someThingElse());

Thanks
7 Answers

ram

6/14/2015 11:59:00 PM

0

Angel Rodriguez <cimadelmundo3000@gmail.com> writes:
>I'm working on a project, and I am defining my style of
>programming functions in javascript. With what I have
>studied, I have seen three methods for working with functions
>and I would like to know what kind of method you would use
>considering scalability, performance, maintenance, etc.

There are actually 28 ways to create objects in JavaScript.

For example, here is another one of them:

I want to define a simple counter object that has
a method that can count upwards by 1.

JavaScript is prototype-based, not constructor-based.

So, we can always ignore constructors and just work
with the prototypes!

I create my global prototype:

var counterPrototype = Object.create( Object.prototype );

. I add my counter method »inc« to the prototype:

Object.defineProperty
( counterPrototype, "inc",
{ value: function()
{ "use strict"; return this.v++; },
configurable: true,
enumerable: false,
writable: true });

. I create new object from my prototype:

var newCounter = Object.create( counterPrototype );

. It still needs a field »v« with the counter value:

Object.defineProperty
( newCounter, "v",
{ value: 0, configurable: true, enumerable: true, writable: true });

. Done! I can now count:

newCounter.inc();

newCounter.inc();

newCounter.inc();

. We have not used constructors, so »newCounter.constructor.name«
is »Object«.

If you often create objects in this manner, of course, you can
put some parts of the above into a library, so that you then can
create objects in this way even more easily.

Advantages of this method: You have more control of the details.
For example, instead of »Object.prototyp« above, I could have
used »null«. Everything above would still work, but now
»newCounter.constructor.name« would be undefined. And at some of
the places above I could have used other values for »configurable«,
»enumerable« or »writable«.

Angel Rodriguez

6/15/2015 1:16:00 AM

0

Excellent !! Thanks !! I agree about the prototypes !!

Thomas 'PointedEars' Lahn

6/15/2015 9:31:00 PM

0

Stefan Ram wrote:

> Angel Rodriguez <cimadelmundo3000@gmail.com> writes:
>> I'm working on a project, and I am defining my style of
>> programming functions in javascript. With what I have
>> studied, I have seen three methods for working with functions
>> and I would like to know what kind of method you would use
>> considering scalability, performance, maintenance, etc.
>
> There are actually 28 ways to create objects in JavaScript.

In your dreams.

> [â?¦]
> I want to define a simple counter object that has
> a method that can count upwards by 1.

And unsurprisingly, in your infinite hubris you have managed to find and
suggest the least compatible, most error-prone, least efficient way to do
that.

> JavaScript is prototype-based, not constructor-based.

Those are not exclusive concepts. A constructor is a way to *initialize* an
instance independent of its prototype.

> So, we can always ignore constructors and just work
> with the prototypes!
>
> I create my global prototype:
>
> var counterPrototype = Object.create( Object.prototype );

â?¦ in an unnecessary complicated way, introducing an unnecessary dependency
on an implementation of ECMAScript Edition 5 and later. Any of

var counterPrototype = {};

var counterPrototype = new Object();

var counterPrototype = Object();

is equivalent to that; with increasing compatibility, but actually also
increasing error-proneness (the â??Objectâ? property can be overwritten).

> . I add my counter method »inc« to the prototype:
>
> Object.defineProperty
> ( counterPrototype, "inc",
> { value: function()
> { "use strict"; return this.v++; },
> configurable: true,
> enumerable: false,
> writable: true });

Which you could have done in the first step, and a readable manner
corresponding to anything that resembles recommended JavaScript code style,
of course:

var counterPrototype = Object.create(Object.prototype, {
inc: {
value: function () { "use strict"; return this.v++; },
configurable: true,
writable: true
}
});

whereas {enumerable: false} is the default, therefore can be omitted.

And even suppose it is supported, the "use strict" declaration serves *no*
purpose there. Backwards-compatible (because the string literal can be
ignored), but overkill.

> . I create new object from my prototype:
>
> var newCounter = Object.create( counterPrototype );
>
> . It still needs a field »v« with the counter value:
>
> Object.defineProperty
> ( newCounter, "v",
> { value: 0, configurable: true, enumerable: true, writable: true });

Again, incompatible overkill. The same can be achieved with

newCounter.v = 0;

as those property attribute values are the defaults for a simple assignment.

> . Done! I can now count:
>
> newCounter.inc();
>
> newCounter.inc();
>
> newCounter.inc();

You donâ??t sayâ?¦

> . We have not used constructors, so »newCounter.constructor.name«
> is »Object«.

Which, almost needless for me to say, is _not_ a good idea. It is useful to
be able to tell apart types of objects. The Google V8 JavaScript console
and Chromium Dev Tools inspector use the prototype chain to get the type,
and the â??constructorâ? property is an efficient way to do that in oneâ??s own
code:

if (!(this instanceof this.constructor))
{
throw new Error("Method called on incompatible object");
}

It is also the most efficient, most refactoring-friendly way to clone an
object â??

return new this.constructor(this);

â?? or to access "static", non-inherited properties shared among all instances
in prototype or instance methods:

this.constructor.foo

> If you often create objects in this manner, of course, you can
> put some parts of the above into a library, so that you then can
> create objects in this way even more easily.

More overkill.

> Advantages of this method: You have more control of the details.
> For example, instead of »Object.prototyp« above, I could have
> used »null«. Everything above would still work, but now
> »newCounter.constructor.name« would be undefined. And at some of
> the places above I could have used other values for »configurable«,
> »enumerable« or »writable«.

Object.create(null) is primarily useful for *data* objects as they would be
missing the .toString() and .valueOf() methods inherited from
Object.prototype by default.

--
PointedEars
FAQ: <http://PointedEars.... | SVN: <http://PointedEars.de...
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-...
Please do not cc me. / Bitte keine Kopien per E-Mail.

Thomas 'PointedEars' Lahn

6/15/2015 9:32:00 PM

0

Angel Rodriguez wrote:

> Excellent !! Thanks !! I agree about the prototypes !!

Do not believe everything that you read.

--
PointedEars
FAQ: <http://PointedEars.... | SVN: <http://PointedEars.de...
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-...
Please do not cc me. / Bitte keine Kopien per E-Mail.

Thomas 'PointedEars' Lahn

6/15/2015 10:09:00 PM

0

Thomas 'PointedEars' Lahn wrote:

> Stefan Ram wrote:
>> . We have not used constructors, so »newCounter.constructor.name«
>> is »Object«.

Only partially true. Historically, Function instances as the one referred
by â??newCounter.constructorâ? did not have a â??nameâ? property per
Specification. This property was implementation-dependent, namely it had
been introduced as a feature of Netscape JavaScript that was later
implemented in Mozilla JavaScript, Opera ECMAScript, and Google V8
JavaScript as well; but according to test results not, for example, in
Microsoft JScript:

<http://PointedEars.de/es-matrix/?filter=Function.prototyp...

This is going to change with ECMAScript Edition 6/2015 where the â??nameâ?
property of Function instances is specified (section 19.2.4.2 of the final
draft).

> Which, almost needless for me to say, is _not_ a good idea. It is useful
> to be able to tell apart types of objects. The Google V8 JavaScript
> console and Chromium Dev Tools inspector use the prototype chain to get
> the type, and the â??constructorâ? property is an efficient way to do that in
> oneâ??s own code:
>
> if (!(this instanceof this.constructor))
> {
> throw new Error("Method called on incompatible object");
> }

This particular suggestion is not completely wrong, but may be misleading.
Usually

(this instanceof this.constructor) === true

so you cannot use that to test the object type /per se/. In an instance or
prototype method you would need a closure to hold a reference to the
original constructor. I thought it would work for (i.e., exclude) data
objects (â??Object.create(null))â?), but in Chromium:

| >>> Foo.prototype.bar.call(Object.create(null))
| Uncaught TypeError: Expecting a function in instanceof check, but got
| undefined
| at Foo.bar (<anonymous>:2:80)
| at <anonymous>:2:19
| at Object.InjectedScript._evaluateOn (<anonymous>:895:140)
| at Object.InjectedScript._evaluateAndWrap (<anonymous>:828:34)
| at Object.InjectedScript.evaluate (<anonymous>:694:21)

This is probably due to section â??12.9.4 Runtime Semantics:
InstanceofOperator(O, C)� in the ES6/2015 final draft, and corresponding
sections in earlier Editions.

The remedy appears to be

if (!(this.constructor && this instanceof this.constructor))

and for strict mode

if (!(this && this.constructor && this instanceof this.constructor))

But again, this would only prevent execution with data objects or objects
where the constructor property has been modified inappropriately.

Also, TypeError is the more appropriate exception type here, although it
appears to be a good idea to define oneâ??s own exception type for this case.

--
PointedEars
FAQ: <http://PointedEars.... | SVN: <http://PointedEars.de...
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-...
Please do not cc me. / Bitte keine Kopien per E-Mail.

Angel Rodriguez

6/16/2015 12:54:00 AM

0

> > Excellent !! Thanks !! I agree about the prototypes !!
>
> Do not believe everything that you read.
>
> --

I don't !!

Thomas 'PointedEars' Lahn

6/16/2015 6:49:00 AM

0

Angel Rodriguez wrote:

>> > Excellent !! Thanks !! I agree about the prototypes !!
>>
>> Do not believe everything that you read.
>>
>> --
>
> I don't !!

You called a very unwise approach â??excellentâ?, you thanked the person
presenting it for it, and you wrote that you �agree� with it. So there is
strong indication that you do.

You are having the common problem of a beginner who does not have enough
experience to judge the quality of what they are reading. There are two
possible mutually exclusive approaches to this problem: a) believe
everything that you read (which evidentially you do), or get the necessary
experience first. One of those approaches is a recipe for disaster.

Please read the FAQ on quoting.

--
PointedEars
FAQ: <http://PointedEars.... | SVN: <http://PointedEars.de...
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-...
Please do not cc me. / Bitte keine Kopien per E-Mail.