10

Clarification:
"JavaScript constructor" should be more properly be written as "javascript constructor" to emphasize that the constructors considered are not just the native JavaScript language constructors, such as Object, Array, Function, etc. but also others, extrinsic to the JavaScript language definition but intrinsic to a browser, such as XMLHttpRequest, The word "JavaScript" is meant to indicate these constructors are expressed and accessed using JavaScript.

some references:

Rhetorically, there are references to constructor functions but NOT constructor objects!

(Facetiously, this is because Objects ARE functions, and Functions are objects!
Why in JavaScript is a function considered both a constructor and an object?
More specifically, objects, or is that obj-eggs?, ARE, ignoring literal instances, instantiations of functions and functions are Object instances of Functions. It is arguable that functions are fundamental to the existence of objects as evidenced by the fact
7. Functions
      precedes
8. Working with Objects
in the MDN docs JavaScript Guide. That section 8, I object!, provides the details needed to create objects using constructors and function instantiations!)

Why are constructors that interface the DOM not functions?

javascript:
  alert([
    "using browser environment:  \n"+window.navigator.userAgent,
     Option, Image, Audio,
       Storage, XMLHttpRequest, Worker, FileReader,
   ] . join("\n\n"));

shows us:

using browser environment:
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.3) Gecko/20100423 Ubuntu/10.04 (lucid) Firefox/3.6.3

[object Option]

[object Image]

[object Audio]

[object Storage]

[object XMLHttpRequest]

[object Worker]

[object FileReader]

but ...

javascript:
  alert([
             XPCNativeWrapper,
  ].join("\n\n"));

(which produces

function XPCNativeWrapper() { [native code] }

)

and JavaScript language constructors ARE functions.

javascript:
  alert([
    "using browser environment:  \n"+window.navigator.userAgent,
             Array, Boolean, Date, Function,
               Number, Object, RegExp, String,
                 Error, Iterator,
  ].join("\n\n"));

gives us:

using browser environment:
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.3) Gecko/20100423 Ubuntu/10.04 (lucid) Firefox/3.6.3

function Array() { [native code] }

function Boolean() { [native code] }

function Date() { [native code] }

function Function() { [native code] }

function Number() { [native code] }

function Object() { [native code] }

function RegExp() { [native code] }

function String() { [native code] }

function Error() { [native code] }

function Iterator() { [native code] }

Community
  • 1
  • 1
Ekim
  • 949
  • 1
  • 8
  • 9
  • `function Object() { [native code] }` Clearly Object is a function. (my tongue is in my cheek and I am being cheeky but ,,,) – Ekim Aug 09 '11 at 04:53
  • Here are some Object objects that ARE functions: `javascript:x=y=z=Object; alert([x,y,z].join("\n\n"))` reiterating, every Object is a function! (not so every object!) – Ekim Aug 10 '11 at 21:03

3 Answers3

3

First:

Objects ARE functions

No, the are not:

> a = function() {}
  function () {}
> a instanceof Object
  true
> b = {}
  Object
> b instanceof Function
  false

The toString method (which is what gets called when you do string concatenation) is not a reliable way to get information about an object. If I use typeof, I get the following:

using browser environment:  
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:5.0.1) Gecko/20100101 Firefox/5.0.1

function

function

function

object

function

function

function

So you see, most of them, apart form Storage, are actually functions (why it does not work for Storage, I don't know).

Also keep in mind that the DOM interface can behave differently than native JavaScript objects.

On the other hand, in Chrome the toString method gives this:

[object Function] 

[object Function] 

[object Function] 

function Storage() { [native code] } 

function XMLHttpRequest() { [native code] } 

function Worker() { [native code] } 

function FileReader() { [native code] }
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • 1
    `typeof Storage === "function"` in chrome12 – Raynos Aug 08 '11 at 20:45
  • The statement "Objects are functions!" was qualified as facetious - but ... Objects ARE Function instantiations! Without functions there are no instantiations, and without instantiations, via `new`, there are no objects! (except for literals such as `{property1:value1, property2:value2}` and predefined entities) – Ekim Aug 08 '11 at 21:46
  • @ekim: Whether all objects are function instantiations is a difficult topic. You could say that everything is eventually created through the `Object` constructor function and inherits from `Object.prototype`. But what does the `Object` function inherit from? From `Function.prototype` which itself inherits from `Object.prototype` again. But `Object.prototype` does not inherit from any other object. – Felix Kling Aug 08 '11 at 22:07
  • @ekim: If you want to have a better insight, I suggest you read the ECMAScript specification: http://ecma262-5.com/ – Felix Kling Aug 08 '11 at 22:13
  • also ... There is a distinction between an object (lower case) instance of arbitrary type, and an Object (capitalized), the constructor for an Object type which IS a function! – Ekim Aug 09 '11 at 00:26
  • The circularity of obj-egg and functional form is self-consistent being neither ambiguous nor contradictory. [Working with Objects](https://developer.mozilla.org/en/JavaScript/Guide/Working_with_Objects) explicitly states that constructors are used to create objects and that in fact in early JavaScript versions (1.1) this was the ONLY way! – Ekim Aug 09 '11 at 00:35
  • @FelixKling let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/2245/discussion-between-ekim-and-felix-kling) – Ekim Aug 09 '11 at 00:36
2

When you alert those values the browser engine is alerting value.toString() so we are talking about why does Function.prototype.toString behave in a strange manner.

The ES5.1 specification states :

15.3.4.2 Function.prototype.toString ( ) An implementation-dependent representation of the function is returned. This representation has the syntax of a FunctionDeclaration.

Note in particular that the use and placement of white space, line terminators, and semicolons within the representation String is implementation-dependent.

The toString function is not generic; it throws a TypeError exception if its this value is not a Function object. Therefore, it cannot be transferred to other kinds of objects for use as a method.

Clearly ES5 states that toString returns an implementation specific string.

If you read the ES Harmony proposals page it states :

function to string – greater specification for problematic Function.prototype.toString (markm, allen)

Here are some more resources :

Basically it's a known issue that toString on function objects (and especially host objects that are also functions) is undefined behaviour. The TC39 committee is already working on standardizing this.

As you can see the host objects are proposed to be standardized in strawman so it's in the air whether that makes it into ES6. However function objects living in ECMA land should have a standardized toString method in ES6 as defined on the harmony proposals page.

Raynos
  • 166,823
  • 56
  • 351
  • 396
  • "15.3.4.2 Function.prototype.toString ( ) An implementation-dependent representation ... has the syntax of a FunctionDeclaration. " Chrome's `function Worker() { [native code] }` qualifies but `[object Worker]` does not. – Ekim Aug 09 '11 at 04:49
  • so ... Why don't `Image`, `Option` etc. conform? Why are they "known issues"? – Ekim Aug 09 '11 at 05:13
  • @ekim again please distinquish between Host objects (part of the browser and DOM) and ES objects. Host objects can do whatever they please because they are host objects. They are as non-standard as you can get. – Raynos Aug 09 '11 at 09:09
  • This is off topic but ... Predefined objects are conventional and de facto standardized, such as JavaScript: (quoting https://developer.mozilla.org/en/JavaScript/Reference#Global_Objects) "Global Objects Standard global objects (by category)" though to be sure browsers from different vendors may "warp" the definitions and occasionally augment the "standard" repertoire. The original question does not ask about "host objects" per se but '"JavaScript" constructors' (which are objects of type Function) only. – Ekim Aug 10 '11 at 19:29
  • The original problem examples do distinguish between the origination of the constructors, whether DOM or native JavaScript, with their string representations that implies the constructor types may sometimes be generic Object and not Function. Why should this be? – Ekim Aug 10 '11 at 20:03
  • @ekim yes but `Image` is a host object not a "JavaScript" constructor. And constructors are always functions. Don't trust `toString`. check `typeof Image`. As mentioned `Function.prototype.toString` is a mess – Raynos Aug 10 '11 at 21:16
  • so ... since `Image` is NOT a constructor then how can it be used as one? ie. `new Image()` – Ekim Aug 12 '11 at 01:39
  • The real issue is why the DOM interface does not subsume the conventions of JavaScript. `Image` is a function and is used as a constructor and so ... (rhetorically), why is it unconventional? ... because someone "goofed". Is `myFunc(){this.prop=2}` a "JavaScript" constructor? a javascript constructor? a constructor? – Ekim Aug 12 '11 at 01:51
  • @ekim Because browser compliance sucks. No-one obheres to standards, everyone does what they wants. – Raynos Aug 12 '11 at 09:17
  • which is why we cannot NOT use stackoverflow.com reliably in any browser! ... there is profound compliance ... and standards do exist for much more than a modest modicum of web page manuscripts – Ekim Aug 12 '11 at 23:52
  • 1
    @ekim sorry _what_ is the standard for the fucntion objects in the DOM? _WHERE_ does it say in the _STANDARDS_ how host constructor objects should behave? **WHY ARE YOU COMPLAINING ABOUT UNDEFINED BEHAVIOUR BEING UNDEFINED!** – Raynos Aug 13 '11 at 09:34
  • r u sure it's undefined? r u sure a complaint is being made? "Why" is a simple question and not a "browser compliance sucks" euphemism. Certainly the examples observed in the original question above ARE defined in the formalities of the programming that implements the browser. – Ekim Aug 15 '11 at 14:59
  • There is no emotional attachment, other than mere curiosity, in pursuing the question of "How or why does (or not) a formal language, ie programmed, program such as a browser realize or contravene the natural language descriptions documenting the same?" – Ekim Aug 15 '11 at 15:16
  • Determining whether or not there is any compliance, consistency and conformity or indeed, if any association is completely absent and undefined, may require serious effort. The Web IDL http://dev.w3.org/2006/webapi/WebIDL/#idl-objects for instance distinguishes "each object ... is ... either a platform object or a user object" but has no references to "host object", which presumably identifies with "platform object", or "host constructor object". – Ekim Aug 15 '11 at 15:54
1

The question might actually be paraphrased as:

"Do JavaScript (ECMAScript) language conventions apply to and qualify other components of the browser such as the programming objects that interface the DOM?"

The original question uses objects that are supposedly of type Function and used as constructors. The examples shows a dichotomy exists with the programming environment and the DOM interface in how they are represented.

If there is this actual dichotomy, is it made explicit?

This may be the actual issue. If so, the original question should be preceded by this to direct attention to the real problem.

references:

ECMAScript language constructor details:

Ekim
  • 949
  • 1
  • 8
  • 9