Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Javascript > Can I know if "new Func()" or "Func()" is called?

Reply
Thread Tools

Can I know if "new Func()" or "Func()" is called?

 
 
jht5945@gmail.com
Guest
Posts: n/a
 
      10-10-2006
For example I wrote a function:
function Func()
{
// do something
}

we can call it like:
var obj = new Func(); // call it as a constructor
or
var result = Func(); // call it as a function

but, can i know if "new Func()" or "Func()" is called?

# sorry my english is not so good

 
Reply With Quote
 
 
 
 
marss
Guest
Posts: n/a
 
      10-10-2006

http://www.velocityreviews.com/forums/(E-Mail Removed) написав:
> For example I wrote a function:
> function Func()
> {
> // do something
> }
>
> we can call it like:
> var obj = new Func(); // call it as a constructor
> or
> var result = Func(); // call it as a function
>
> but, can i know if "new Func()" or "Func()" is called?
>
> # sorry my english is not so good


typeof(obj) always is "object", typeof(result) depends on result value
that Func() returns.
Sorry, my English also leaves much to be desired.

 
Reply With Quote
 
 
 
 
VK
Guest
Posts: n/a
 
      10-10-2006
How can I know if "new Func()" or "Func()" is called?

If a function is called as a constructor, it's running in the scope of
the newly created object, so [this] is pointing to the said object. If
it's called as a function, for top level functions [this] is set to
window object (talking about a regular script executed in a HTML
document) Thus in the most primitive form the check will be:

function Func() {
if (this == window) {
// called as function
}
else {
// called as constructor
// or (attention!) as method of an object
}
}

That's work reliable only to sort out cases of top-level constructors
called as regular functions. For more sophisticated cases you should
instruct your constructor in advance which [this] values it will
accept, say via internal variable in your constructor.

 
Reply With Quote
 
Richard Cornford
Guest
Posts: n/a
 
      10-10-2006
VK wrote:
> How can I know if "new Func()" or "Func()" is called?
>
> If a function is called as a constructor, it's running in the
> scope of the newly created object,


The scope within a function is not influenced by how it is called.
There is no such thing as "the scope of a newly created object" (unless
the object is a function).

> so [this] is pointing to the said object.

<snip>

The - this - value is not an aspect of a function's scope. The - this -
value and the applicable scope are characteristics of the execution
context.

Richard.

 
Reply With Quote
 
VK
Guest
Posts: n/a
 
      10-10-2006
> > If a function is called as a constructor, it's running in the
> > scope of the newly created object,

>
> The scope within a function is not influenced by how it is called.
> There is no such thing as "the scope of a newly created object" (unless
> the object is a function).


Are you kidding or being *really* nitpicking? In case ifthe latter I'm
re-phrasing: "when called as a constructor, the function has the newly
created object instance at the top of the scope chain".

A new instance is created at the moment of execution "new SomeObject()"
statement. So it the moment SomeObject() function is called, a new
instance of SomeObject object is already created and placed at the top
of the scope chain so you could fill it with "this.something =..." etc.
That should be clear that you are working with an instance of
SomeObject, not with a generic Object object. Thusly "this.something
=..." etc. is an optional step, you can have a constructor as simple
as:
function SomeObject(){}
and then
var obj = new SomeObject();
which gives you an empty object just like new Object() *but* being an
instance of SomeObject (so its constructor is set properly, instanceof
will act properly and so on).

<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<script type="text/javascript">
function CustomObject() {
/* say we want this function to be used
* only as constructor, and not as a
* regular function
*/
window.alert(this instanceof CustomObject);

if (this == self) {
throw new Error('Illegal constructor call');
}
else {
this.property1 = 'property1';
this.toString = CustomObject.toString;
}
}
// override toString to prevent source dump:
CustomObject.toString = function(){return '';}

try {
var foo = new CustomObject();
window.alert(foo.property1);

// noop:
var bar = CustomObject();
}
catch(e) {
window.alert(e.message);
}
</script>
</head>

<body>

</body>
</html>

 
Reply With Quote
 
Richard Cornford
Guest
Posts: n/a
 
      10-10-2006
VK wrote:
>>> If a function is called as a constructor, it's running in the
>>> scope of the newly created object,

>>
>> The scope within a function is not influenced by how it is called.
>> There is no such thing as "the scope of a newly created object" (unless
>> the object is a function).

>
> Are you kidding or being *really* nitpicking?


I am correcting your misapplication of technical terminology that has a
very precise (and important) meaning.

> In case ifthe latter I'm re-phrasing: "when called as a constructor,
> the function has the newly created object instance at the top of the
> scope chain".


That is worse because instead of being an inappropriate use of the
terminology it is an absolutely false statement.

The execution context for a function call (including a function called
as a constructor) the object at the top of the scope chain is the
Activation/Variable object for that execution context. The object being
constructed does not appear on the scope chain for that execution
context at all (unless explicitly added using a - with - statement
within the constructor, and then it is not really the scope chain of
the execution context but the scope chain of the - with - statement. ).

> A new instance is created at the moment of execution "new SomeObject()"
> statement. So it the moment SomeObject() function is called, a new
> instance of SomeObject object is already created and placed at the top
> of the scope chain


When the process of calling the constructor gets to the internal
[[Call]] method of the function object a new instance of the Native
ECMAScript object has been created (and its [[Prototype]] property
set), but that object is *not* placed on the scope chain, it is
assigned to the - this - value.

> so you could fill it with "this.something =..." etc.


Nothing on the left of that assignment expression is resolved against
the scope chain.

> That should be clear that you are working with an instance of
> SomeObject, not with a generic Object object. Thusly "this.something
> =..." etc. is an optional step, you can have a constructor as simple
> as:
> function SomeObject(){}
> and then
> var obj = new SomeObject();
> which gives you an empty object just like new Object() *but* being an
> instance of SomeObject (so its constructor is set properly, instanceof
> will act properly and so on).

<snip>

And that hangs on the assignment to the [[Prototype]] property of the
newly created object, and has nothing to do with scope chains at all.

Richard.

 
Reply With Quote
 
VK
Guest
Posts: n/a
 
      10-10-2006

Richard Cornford wrote:
> The object being
> constructed does not appear on the scope chain for that execution
> context at all (unless explicitly added using a - with - statement
> within the constructor, and then it is not really the scope chain of
> the execution context but the scope chain of the - with - statement. ).
> When the process of calling the constructor gets to the internal
> [[Call]] method of the function object a new instance of the Native
> ECMAScript object has been created (and its [[Prototype]] property
> set), but that object is *not* placed on the scope chain, it is
> assigned to the - this - value.


Is this what ECMAScript 3ed ed. mumbling? In such case I lost very
little by not reading it (except few paragraphs occasionally).

Let me explain how does it *really* work and ever worked on any UA with
javascript support, but first let me explain to you that [this]
statement points to the *current object*, thus to the object located at
the top of the scope chain. This way a statement like "object is *not*
placed on the scope chain, it is assigned to the - this - value" has no
programming sense whatsoever.

Now how does it *really* work:

var obj = new MyObject();

1) create an empty instance of MyObject object
2) call MyObject() constructor
2) place newly created instance at the top of the constructor scope
chain
3) execute MyObject() statements (if any)
4) if there is no [return] statement in the constructor, then return
the newly created instance of MyObject object (equivalent of "return
this;")
If there is [return] statement in the constructor and it is not "return
this;", then return whatever pointed by this statement. The newly
created instance of MyObject object - unless it was referenced
somewhere else in the constructor - will remain dereferenced and soon
removed by Garbage Collector.

The above can be discussed for better wording, but any source stating a
different *schema* is a junk to disregard: in application to any UA.

 
Reply With Quote
 
Matt Kruse
Guest
Posts: n/a
 
      10-10-2006
VK wrote:
> Let me explain how does it *really* work and ever worked on any UA
> with javascript support


You're wrong. Can't you even test your own theories by typing a few lines of
code?

>, but first let me explain to you that [this]
> statement points to the *current object*, thus to the object located
> at the top of the scope chain. This way a statement like "object is
> *not* placed on the scope chain, it is assigned to the - this -
> value" has no programming sense whatsoever.


If your statements were true, then this code:

function Obj() {
this.value="xyz";
alert(value);
}
var x = new Obj();

should alert "xyz". Since according to you, "this" is put into the scope
chain.

However, it doesn't. It causes an error because 'value' is undefined.
How can you explain this BAFFLING behavior?

--
Matt Kruse
http://www.JavascriptToolbox.com
http://www.AjaxToolbox.com


 
Reply With Quote
 
VK
Guest
Posts: n/a
 
      10-10-2006
> You're wrong. Can't you even test your own theories by typing a few lines of
> code?


That is not a theory: that is a well-known fact used in thousands of
lines of code I typed. The OP question was " how can I know if "new
Func()" or "Func()" is called?". That was answered by using *my*
knowledge of JavaScript mechanics. If you see my solution doesn't work,
then point the error so OP would get a better answer. If you don't like
my answer just because "if cannot work because it cannot work this way
- even it works" when it's not my problem.

> If your statements were true, then this code:
>
> function Obj() {
> this.value="xyz";
> alert(value);
> }
> var x = new Obj();
>
> should alert "xyz". Since according to you, "this" is put into the scope
> chain.
>
> However, it doesn't. It causes an error because 'value' is undefined.
> How can you explain this BAFFLING behavior?


That's easy, but first let's us close the question of the the real
constructor mechanics (if anyone still have some doubts):

<script type="text/javascript">
function MyObject() {
window.alert(this instanceof MyObject);
window.alert(this.constructor == Object.constructor);
window.alert(this.prototype == Object.prototype);
}

var obj = new MyObject();
</script>

- watch what is true and what is not.

Now about your case: that is not a "baffling" behavior but a very well
thought machanics for object constructors in JavaScript: which doesn't
have neither default object accessor shortcut (like VB) nor formal
members declarations like say Java. That would be a holy mess then in
cases like:

function MyObject(width, height) {
this.width = width;
this.height = height;
}
//what to assign to what?

So the default object pointer (and this is what [this] is) is acting a
bit differently in the context of a constructor call. Does it affect to
OP's problem?

 
Reply With Quote
 
runsun@gmail.com
Guest
Posts: n/a
 
      10-10-2006
(E-Mail Removed) wrote:

> but, can i know if "new Func()" or "Func()" is called?


This should work:

function asConstructor(that)
{
return that instanceof arguments.callee.caller
}

function f()
{
alert(asConstructor(this))
}

var obj = new f(); // ==> true
f(); // ==> false

 
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
know can I know how much object has been created??? sayoyo@yahoo.com Ruby 2 03-31-2006 08:09 PM
"Microsoft Certification - It's how they know you know" MatrixVic MCSD 0 02-03-2006 02:52 AM
ISAKMP NAT problem (I know it can be done but don't know how) Rogier Mulder Cisco 1 01-13-2005 08:48 PM
I know, I know, I don't know Andries Perl Misc 3 04-23-2004 02:17 AM
Don know Perl, don't know what's broke - re - type1inst!! DP Perl 0 07-17-2003 10:22 PM



Advertisments