VK said:
Exactly my point. As getElementsByTagName() returns an
HTMLCollection,
The getElementsByTagName method is specified as returning a _NodeList_
not an HTMLCollection. It is a Core DOM method and apples to non-HTML
documents in addition to HTML documents. (Granted if you have a host
object for interaction with JS that implements HTMLCollection there is
no reason not to use that same object when a NodeList is called for as
HTMLColleciton implements all of the NodeList interface).
JavaScript automatically converts arrayObject from Array
type to HTMLCollection type to accomodate new data structure.
(You can easy observe it by checking method/properties "before"
and "after").
It took me a while but I finally worked out which misconception had
resulted in this nonsense.
You are thinking of - arrayObject - as, in some sense, having a type.
In javascript all variables are in reality properties of objects. Global
variables are properties of the global object, so in the code above the
variable 'arrayObject' is a property of the global object named
'arrayObject'. Properties of objects that exist have values and an
assignment operation assigns a value to a property. The properties
themselves have no 'type', only a value. The value assigned to a
property will have a type, and can be of any type defined in the
language (though that just means one of: Undefined, Null, Boolean,
Number, String or Object (ECMA 262 3rd edition section 4.3), as that is
all of the types that can be explicitly assigned to property values).
Following:-
var arrayObject = new Array();
The property of the global object 'arrayObject' refers to an instance of
a javascript Array. But the assignment:-
arrayObject = document.getElementsByTagName('P');
- does not change the type of 'arrayObject' it changes its value into a
reference to an object implementing the NodeList interface.
And the Array object that was originally assigned to 'arrayObject' is
not changed in any way by the subsequent assignment (except that if it
is no longer referred to by any object properties it may be garbage
collected).
So it is effectively switching interfaces for data,
and this is what actually "casting" is.
So you are defining 'casting' as changing the value of an object's
property from a reference to object A into a reference to object B?
Simply in typed languages casting doesn't
happen "by itself", so I call it "background casting".
Overall it's the same as
var myVar = 1; // see what methods you can apply here
Assigning a numeric value to a property of the global object.
myVar = "Hello world!"; // here
Then assigning a string value to that same property.
myVar = true; // and here
And finally assigning a boolean value. No casting there, not even any
type-conversion.
In a strongly typed language a variable (and/or an object member) must
be declared as some type. As a result it would not be legal to assign a
sequence of value of the 'wrong' type. That just doesn't apply to
javascript.
// etc.
myObject.toString();
The most primitive type of explicit casting I'm sure you used a while
already.
I was talking in terms of casting objects into different types, in the
way that in Java you may cast an object into the 'type' of an interface
that it implements. As javascript treats all objects as being the same
type there are no other types to cast them to.
You can type-convert, including converting an object into a string
primitive, which is done by implicitly or explicitly calling its
toString method (and may error if the object is a host object taking
advantage of the provision for it not to implement a toString method).
Type-conversion only takes place between javascript's defined types:
Undefined, Null, Boolean, Number, String or Object. Object is the only
object type but can be type-converted to any primitive type except
Undefined and Null. It is also not possible to type-convert any other
primitive to Undefined or Null. Undefined and Null may be type-converted
to any other primitive type but cannot themselves be type-converted into
objects, unlike the other primitive types.
This description fits to any existing OOP language.
The same object can implement different interfaces at different times?
That is exactly the type of behaviour that strong typing prevents. Now,
one object (in, for example, Java) may implement several interfaces, but
that object will implement all of those interfaces at all times.
The main specifics of JavaScript that it doesn't
incapsulate objects (as well as primitive data types),
so any second they are ready to be whatever you're
pushing on them from the right side of the
assignement.
This seems your main misconception here. The thing to the left in an
assignment has no concept of 'type' at all. It is just a slot into which
a value may be placed. Any value of any type. In class based languages
those slots may be qualified as only accepting a single type, but
javascript is loosely typed and is not class-based.
But your misconception should become obvious to you when you consider
that you wrote:-
| (Collection)arrayObject = document.getElementsByTagName('P');
- with its implication that you would cast the left hand side of an
assignment in (I assume) Java. You would not, the left hand side is
fixed when it is declared, it is the right hand side you would be
casting, if at all.
You give them collection - it will become
HTMLCollection, Array - so be array, number - so the
better. But until the next "transformation" (if you don't
like the term "casting") they are particular objects with
particular property/methods (added right to the instance,
native, inherited or prototyped).
Consider:-
var a = new Array();
var b = a; // b now refers to the same array as a
var c = a; // c now refers to the same array as a
c = 'any string';
- you would be implying that the act of assigning a string literal to c
would in some sense 'transform' the object that it previously referred
to (the Array object that was originally assigned to a and is still
referred to by a and b). Try it, you will not find any evidence of any
transformation in the Array, and it certainly has not changed into a
string.
Class is simply a factory of objects with predefined
behaviors.
But the behaviour of dynamic objects is not fixed, so not defined, so
not pre-defined.
Each object in JavaScript has its constructor property
reffering to its creator.
Having the same creator does not imply having the same behaviour,
structure or properties. in javascript.
function MyObject(){
}
var a = new MyObject();
MyObject.prototype = {type:'I am one type'};
var b = new MyObject();
MyObject.prototype = {className:'I am different'};
var c = new MyObject();
alert(a.type); // 'undefined'
alert(b.type); // 'I am one type'
alert(c.type); // 'undefined'
alert(a.className); // 'undefined'
alert(b.className); // 'undefined'
alert(c.className); // 'I am different'
alert(a.constructor == b.constructor); // 'false'
alert(b.constructor == c.constructor); // 'true'
alert(a.constructor == c.constructor); // 'false'
alert(a.constructor == MyObject); // 'true'
alert(b.constructor == MyObject); // 'false'
alert(c.constructor == MyObject); // 'false'
- One constructor function, three distinct object 'types', only two of
them share the same 'constructor' property and that is not a reference
to the function that constructed them.
Or:-
function MyObject_1(){
}
function MyObject_2(){
}
MyObject_2.prototype = MyObject_1.prototype;
var a = new MyObject_1();
var b = new MyObject_2();
alert(a.constructor == b.constructor); // 'true'
- Two different constructor functions, creating identical objects that
even think they have the same constructor.
To avoid the word "class" we could call it "object
constructor" but it would be a bizarre term.
And an utterly futile suggestion given the loose relationship between
constructor functions and the objects they construct.
Just say it: "class constructor",
and you will feel a gread relieve in your mind ;-)
No, I will continue to think of javascript as the class-less language
that it is. And reserve the term class for the sub-set of object
implementations that are designed to be approximately analogous in their
definition _and_ employment with classes in class-based languages.
Terminology that I shall use only when doing so is appropriate an
advantageous, and without letting it get in the way of my appreciation
of what javascript really is: loosely typed, class-less and dynamic.
Richard.