>
> Are there any strong reasons *not* to allow a given class instance to
> be created with this syntax:
>
> var x = Foo();
>
> as opposed to:
>
> var x = new Foo():
>
> ?
>

Hi Stephen,

I believe that is is very useful to separate these two cases. Although it is
possible to emulate "new" behavior via the means you mentioned below, users
should know that there are crucial differences between these two calls:

- "new" ignores return value of ctor function;
- "new" sets the hidden _proto_ property so prototype inheritance works;
- "new" call uses "this" keyword as a reference to new instance being
created, non-new call uses current scope (global or any other if ".call"ed
or ".apply"ed).

In pure JS, it is also possible to simulate "new" keyword by clever
definition of the Foo functions, but my opinion is that the code should not
automatically fix programmer's poor abilities.



>
> When a v8-bound ctor is called we can check IsConstructorCall() to
> determine if 'new' was used, and behave
> differently in that case. My question is, however, is there a good
> reason (in terms of class design) to differentiate between the two
> forms of calls (for the generic case)?
>


Nice, I was always checking the number of internal fields instead of this (0
internal fields when class is supposed to have >0 => not a constructor
call). This is surely a better way to go.


Ondrej




> On a related note: i came across the following trick today for
> generically handling the "treated 'Foo()' as 'new Foo()'" case, and
> thought it might be useful to someone out there:
>
>
>        static Handle<Value> yourConstructorFunction( const Arguments &
> argv )
>        {
> #if 1
>            /**
>               Allow construction without 'new' by forcing this
>               function to be called in a ctor context...
>            */
>            if (!argv.IsConstructCall())
>            {
>                const int argc = argv.Length();
>                Handle<Function> ctor( Function::Cast(*argv.Callee
> ()));
>                std::vector< Handle<Value> > av(static_cast<size_t>
> (argc),Undefined());
>                for( int i = 0; i < argc; ++i ) av[i] = argv[i];
>                return ctor->NewInstance( argc, &av[0] ); // calls
> yourConstructorFunction() again
>            }
> #else // this was my code before ^^^^
>            /**
>               Why have this limitation? If we don't, v8 pukes when
>               the ctor is called, with
>               "v8::Object::SetInternalField() Writing internal field
>               out of bounds".
>            */
>            if (!argv.IsConstructCall())
>            {
>                std::ostringstream os;
>                os << "The "<< ClassOpsType::ClassName() << "
> constructor cannot be called as function!";
>                return ThrowException(String::New(os.str().c_str()));
>            }
> #endif
> ...
>
> }
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users
-~----------~----~----~----~------~----~------~--~---

Reply via email to