Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Javascript > Perfect function forwarding

Reply
Thread Tools

Perfect function forwarding

 
 
Alexis Nikichine
Guest
Posts: n/a
 
      12-27-2005
Hello,

Today, I have a function:

function f()
{
}


and am looking for a way of distinguishing, from inside f, whether it
has been called with new, or not.

function f()
{
if( ... )
return new forwardedFunction(...);
else
return forwardedFunction();
}

Iow, are we [[Call]]ed or [[Construct]]ed. Can't get around it...

Any help appreciated,

Alexis

--
Some domain is free
 
Reply With Quote
 
 
 
 
Thomas 'PointedEars' Lahn
Guest
Posts: n/a
 
      12-27-2005
Alexis Nikichine wrote:

> --
> Some domain is [...]


somedomain.fr is not. Yet.

<URL:http://www.interhack.net/pubs/munging-harmful/>


PointedEars
 
Reply With Quote
 
 
 
 
Rob Williscroft
Guest
Posts: n/a
 
      12-27-2005
Alexis Nikichine wrote in news:43b17beb$0$21746$(E-Mail Removed) in
comp.lang.javascript:

[snip]

> and am looking for a way of distinguishing, from inside f, whether it
> has been called with new, or not.
>
> function f()
> {
> if( ... )
> return new forwardedFunction(...);
> else
> return forwardedFunction();
> }
>
> Iow, are we [[Call]]ed or [[Construct]]ed. Can't get around it...
>


var GLOBAL = this;
function f()
{
alert( this === GLOBAL );
}

f();
new f();

Rob.
--
http://www.victim-prime.dsl.pipex.com/
 
Reply With Quote
 
Thomas 'PointedEars' Lahn
Guest
Posts: n/a
 
      12-27-2005
Rob Williscroft wrote:

> Alexis Nikichine wrote [...]:
>> and am looking for a way of distinguishing, from inside f, whether it
>> has been called with new, or not.
>>
>> function f()
>> {
>> if( ... )
>> return new forwardedFunction(...);
>> else
>> return forwardedFunction();
>> }
>>
>> Iow, are we [[Call]]ed or [[Construct]]ed. Can't get around it...

>
> var GLOBAL = this;
> function f()
> {
> alert( this === GLOBAL );
> }
>
> f();
> new f();


this == GLOBAL

should suffice. However, either test does not work for functions called
from non-global method context.


PointedEars
 
Reply With Quote
 
Randy Webb
Guest
Posts: n/a
 
      12-27-2005
Thomas 'PointedEars' Lahn said the following on 12/27/2005 1:27 PM:
> Alexis Nikichine wrote:
>
>
>>--
>>Some domain is [...]

>
>
> somedomain.fr is not. Yet.
>
> <URL:http://www.interhack.net/pubs/munging-harmful/>


Are you actually to the point in life where you have nothing better to
do than pedantically whine about a snippet in a signature?

It might not be so bad if you would reference a decent article instead
of an outdate worthless reference.

None of which is relevant or even remotely related to this thread and/or
this Newsgroup.

--
Randy
comp.lang.javascript FAQ - http://jibbering.com/faq & newsgroup weekly
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
 
Reply With Quote
 
Lasse Reichstein Nielsen
Guest
Posts: n/a
 
      12-28-2005
Alexis Nikichine <(E-Mail Removed)> writes:

> Today, I have a function:
>
> function f()
> {
> }
>


> and am looking for a way of distinguishing, from inside f, whether it
> has been called with new, or not.


Since the only difference visible inside f will be the value of the
"this" operator, this will have to be sufficient. It cannot be
completely safe, but unless someone is deliberatly trying to cheat, it
should be fairly safe. Javascript has no language based protection
against malicious code.

You could try checking whether the value of "this" could be a new
object created with "new f()". E.g., check
this.constructor == f
or
this instanceof f

I can't see any way of ensuring that f.prototype is the first object
in the prototype chain, so the above can be tricked using, e.g.,

var fake = new f();
// fiddle with fake
f.call(fake); // can't see that fake is not a new object

Indeed, there shouldn't be a way to see it. The "new" operator creates
the object, but the call to "f" to initialize it afterwards is just a
normal function call (calling the [[Call]] method of the function).

/L
--
Lasse Reichstein Nielsen - http://www.velocityreviews.com/forums/(E-Mail Removed)
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
 
Reply With Quote
 
Alexis Nikichine
Guest
Posts: n/a
 
      12-28-2005
Lasse Reichstein Nielsen wrote:

> Since the only difference visible inside f will be the value of the
> "this" operator, this will have to be sufficient. It cannot be
> completely safe, but unless someone is deliberatly trying to cheat, it
> should be fairly safe. Javascript has no language based protection
> against malicious code.
>
> You could try checking whether the value of "this" could be a new
> object created with "new f()". E.g., check
> this.constructor == f
> or
> this instanceof f


Oh thanks, I finally settled on:

function f()
{
if( this.constructor == f )
return new forwardedFunction();
else
forwardedFunction();
}

The good of it is that no object with f as a constructor will ever
escape that f, and that it breaks none of my code.

> I can't see any way of ensuring that f.prototype is the first object
> in the prototype chain, so the above can be tricked using, e.g.,
>
> var fake = new f();
> // fiddle with fake
> f.call(fake); // can't see that fake is not a new object


So, is my f really fooled with this ?

Since fake.constructor == forwardedFunction, which implies
fake.constructor != f, I guess that forwardedFunction will be called,
and not newed. Unless I'm mistaken, of course.

The only "fiddling with fake" that I could find that messed things up
was to hack f construcotr property:

fake.constructor = f;
f.call(fake); // Ok, gotcha !

And since in my case, f is actually an anonymous inner function, this
fiddling is not possible.

So finally, here is my definite function interceptor, and I claim it is
bullet-proof (but would be interested in being proved wrong):

// richard cornford's "constructWithArgs":

var constructWithArgs = (function(){
function Dummy(){ ; }
return (function(fun, args){
Dummy.prototype = fun.prototype;
var tmp = new Dummy;
fun.apply(tmp, args);
return tmp;
})
})();

// precondition: obj[memberFunction] must be a function
function intercept( obj, memberFunction )
{
obj[memberFunction] = function() {
alert( "BEFORE call to " + memberFunction);
try
{
if( constructor == arguments.callee )
return constructWithArguments( obj[memberFunction], arguments );
else
return obj[memberFunction].apply( this, arguments );
}
finally
{
alert("AFTER call to " + memberFunction);
}
}
}

Actually I could make up one bullet:

intercept( this, "Array" );
a = new Array();
alert( a.constructor == Array ); // false !!

but it's not the interceptor that breaks, but the interceptor that
breaks outside code.

> Indeed, there shouldn't be a way to see it. The "new" operator creates
> the object, but the call to "f" to initialize it afterwards is just a
> normal function call (calling the [[Call]] method of the function).


Well, I was imaginating in the wrong direction: I was somehow looking
for a way to determine whether 'this' was a fresh, new and immaculate
object. Dreaming out loud, I suppose.

Cheers,

Alexis
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
strange compile problem regarding const-ref v.s. perfect forwarding huili80@gmail.com C++ 3 10-29-2012 09:11 PM
Perfect Forwarding in Runtime (rvalue reference) dervih C++ 3 07-13-2012 02:03 PM
using std::function, std::bind, perfect forwarding Andrew Tomazos C++ 1 12-23-2011 10:19 AM
Specializing Perfect Forwarding Templates? Scott Meyers C++ 20 03-16-2011 07:07 PM
Perfect Forwarding + static_assert [C++0x] Scott Meyers C++ 6 12-05-2010 08:21 PM



Advertisments