(short article)
We often come across situations, where we need to check, whether a passed object is of a certain type. for standard objects (1) it is quite common to use the typeof operator for such tests. Objects coming from the document tree (2) are usually tested through their nodeType property.
A common field, where this is necessary, are functions or methods, that require a function as parameter, namely addEventListene r(), call() and apply().
Using interfaces, you can rewrite that as
admittedly, there is not that much advantage of instanceof over typeof, but we have not yet touched DOM.
Suppose you are walking through the document tree, looking for an element.
Are you sure that after the last object "undefined" is returned? wouldn’t be a "as long as obj is an element" be a better condition? (yes, it would)
Interfaces also posses some very useful properties from objects – inheritance. that is, an interface can match a number of different objects, as long as they have the required properties*.
We see here the basic use: I want to use a property named data (return the text of a text node), the literal approach to use it without error is "if there is a data property, access it".
We can’t use the following, because this tests not for the property, but for the content of the property.
we could use
but that’s essentially the same as
because the data property is part of the CharacterData interface, from which the Text interface inherits. So why don’t I use CharacterData? Because comment nodes also inherit from that and I don’t want comment text this time.
Personally, I find that way more descriptive than
* the parentNode property is part of the Element interface (well, originally from the Node interface, but Element extends Node).
** methods count as properties too, got something to do with the object implementation
We often come across situations, where we need to check, whether a passed object is of a certain type. for standard objects (1) it is quite common to use the typeof operator for such tests. Objects coming from the document tree (2) are usually tested through their nodeType property.
A common field, where this is necessary, are functions or methods, that require a function as parameter, namely addEventListene r(), call() and apply().
Code:
// this is a necessary test if [I]fn[/I] is passed as parameter
if ("function" != typeof fn)
{
throw new Error("Supplied argument is not a function.");
}
this.addEventListener("event", fn, false);
Code:
// this is a necessary test if [I]fn[/I] is passed as parameter
if (!(fn instanceof Function))
{
throw new Error("Supplied argument is not a function.");
}
this.addEventListener("event", fn, false);
Suppose you are walking through the document tree, looking for an element.
Code:
while ("undefined" != typeof obj)
{
// do something with obj
obj = obj.parentNode;
}
Code:
while (obj instanceof Element)
{
// do something with obj
obj = obj.parentNode;
// the parent node of an element is always another element*
}
Code:
// match all text nodes
if (obj instanceof Text)
{
var text = obj.data;
}
We can’t use the following, because this tests not for the property, but for the content of the property.
Code:
if (obj.data)
Code:
if ("data" in obj)
Code:
if (obj instanceof CharacterData)
Personally, I find that way more descriptive than
Code:
// match all text nodes
if (3 == obj.nodeType || 4 == obj.nodeType)
{
var text = obj.data;
}
** methods count as properties too, got something to do with the object implementation