0

First, Im away from keyboard, just checking on my phone over jsconsole app. Second, i got a simple snippet like this:

const foo = document.getElementsByClassName('bar');

foo instanceof HTMLCollection // true
foo[0] instanceof HTMLElement // false

I just wondering why foo[0] return false when the element it doesnt exist. Is that caused by undefined element? Or what? Any refer to this? Please give me some quotes, thankyou!

Rafv
  • 261
  • 2
  • 9
  • 1
    why would `undefined` inherit from HTMLElement? – Kaiido Feb 01 '19 at 05:44
  • I dont know, i just console foo and it return undefined – Rafv Feb 01 '19 at 05:52
  • 1
    It's a feature of javascript that if you try to access a non–existent property of an object (like `foo[0]`), it returns *undefined* (i.e. the value *undefined*). So your expression resolves to `undefined instanceof HTMLElement`. I think you know what the answer will be. Incidentally, it is not *required* for implementations to implement prototype inheritance for HTML elements, it's just convenient to do so. – RobG Feb 01 '19 at 05:57
  • Please, dont judge me like 'i think you know what the answer would be'. I just need an anwer of 'why' cause I dont really understand about prototype inheritence of the htmlelement. 'Javascript feature' thanks! – Rafv Feb 01 '19 at 06:05
  • 2
    If you don't understand prototype inheritance, how do you understand the result of calling *instanceof*? It just tests if the public prototype of the second object (HTMLElement) is on the internal *prototype* chain of the first object. *undefined* is a primitive value, it doesn't have an internal prototype, it's not an instance of anything so `undefined instanceof anyObjectYouLike` will always return false. If that doesn't do it, I'll write a more explicit answer. – RobG Feb 01 '19 at 06:12
  • There you 'undefined is a primitive value and it doesnt have internal prototype' i miss this... ;D thanks you so much robg! – Rafv Feb 01 '19 at 06:19
  • @Rafv—the algorithm for *instanceof* actually just looks to see if it's an object and if not, returns false, which is just to shortcut the process. :-) – RobG Feb 01 '19 at 06:25

2 Answers2

1

getElementsByClassName will return a NodeList which is a HTMLCollection. So if there is no element with given class, you will still get an empty Node List.

However, when you try to access oth element, since its an empty list, you get undefined (as rightly suggested by kaiido). Hence you get false.

Following is a sample representation:

var test = document.getElementsByClassName('test');

console.log(Object.prototype.toString.call(test))
console.log(Object.prototype.toString.call(test[0]))
Rajesh
  • 24,354
  • 5
  • 48
  • 79
  • Ah, `Object.prototype`. Thanks a lot man! 'If there is no element with given class, you will get an empty Node List' = empty NodeList, thanks rajesh!! – Rafv Feb 01 '19 at 06:13
  • 1
    @Rafv— *Object.prototype* is irrelevant here, it's just a way to access the built–in *Object.prototype.toString* method which returns the "class" of the *this* value it's called on, it can also be done with `{}.toString.call(...)`. – RobG Feb 01 '19 at 06:22
  • @RobG can you provide me your relevant mean please? – Rafv Feb 01 '19 at 06:29
  • @Rafv—[*Get the name of an object's type*](https://stackoverflow.com/questions/332422/get-the-name-of-an-objects-type/332429?r=SearchResults&s=3|112.3930#332429). – RobG Feb 01 '19 at 06:55
  • @RobG thanks to your refer, it would be my great dinner tonight! – Rafv Feb 01 '19 at 07:03
  • 1
    @Rafv—generally in javascript if you think you need to use *instanceof* you're probably doing something wrong. It's not a strongly typed language and objects can inherit from anywhere (pretty much), so while type checking has its place, "class" checking really doesn't. Have a look through some well regarded libraries and see how they use *instanceof*, etc. – RobG Feb 01 '19 at 21:46
0

Perhaps your question is that "HTMLCollection" / "HTMLElement" does not matter.

const arr = []
arr // []
arr[0] // undefined
arr[0] instanceof HTMLElement // false
t_yamo
  • 781
  • 1
  • 12
  • 21
  • So you're poiting if any array or object is not set (yet), it would return false? @t_yamo – Rafv Feb 01 '19 at 06:00
  • 1
    array is set, but array[0] is not set. array[0] is undefined and undefined instanceof Xxx is false. – t_yamo Feb 01 '19 at 06:02
  • oh, sorry there is type miss `arr instanceof HTMLElement // false` -> `arr[0] instanceof HTMLElement // false` – t_yamo Feb 01 '19 at 06:04