I was wonder by that when worked with chrome devtools.
But it seems that typeof <object>
is a "function".
I haven't found any explanation or references.
Here is the simple example: https://jsfiddle.net/fez34zbf/
HTML:
<object></object>
<video></video>
JS:
console.log(typeof document.querySelector('object'));
console.log(typeof document.querySelector('video'));
console results will be:
function
object
Any ideas?
A function object, or functor, is any type that implements operator(). This operator is referred to as the call operator or sometimes the application operator. The C++ Standard Library uses function objects primarily as sorting criteria for containers and in algorithms.
In JavaScript, functions are first-class objects, because they can have properties and methods just like any other object. What distinguishes them from other objects is that functions can be called. In brief, they are Function objects.
An object is a collection of properties, and a property is an association between a name (or key) and a value. A property's value can be a function, in which case the property is known as a method. In addition to objects that are predefined in the browser, you can define your own objects.
Object is a function, but not every object is a function.
As already mentioned typeof must return "function"
for all Objects that have a [[Call]]
internal method.(spec). So the interesting part is that instances of HTMLObjectElement
for some reason have a [[Call]]
internal method.
There are bug reports for this for firefox as well as chrome. While there are no replies on the firefox issue on the chrome issue there is an explanation where [[Call]]
gets added to HTMLObjectElement
Yes, that's correct. SetCallAsFunctionHandler() makes the object callable according to EcmaScript, hence we have to return "function" for typeof.
SetCallAsFunctionHandler
seems to be some implementation detail in v8. According to the issue chrome used to report object
as the typeof
instances of HTMLObjectElement
but they changed it to be compatible with firefox.
Now why is there a [[Call]]
internal method on HTMLObjectElement
? As this stackoverflow answer implies this seems to be used by some plugins. HTMLObjectElement
is used by plugins ( e.g. flash ). And some of these plugins probably except input using this function.
Looking at the source code of chromium there seems to be some code that indeed handles some legacy call back (V8HTMLEmbedElement.cpp
and V8HTMLPlugInElementCustom.cpp
).
Also in this firefox ticket this is confirmed
why on earth are Embed/Object elements callable in the first place? [...] As far as anyone can tell, because some plug-ins do something when you call them and no one wants to break that for compat reasons...
I did not find any specification that defines this behavior. The html5 spec mentions a legacy caller operation but does not define exactly how it works
So as a summary: typeof document.createElement('object')
is "function"
because it has a [[Call]]
internal method. And it has a [[Call]]
internal method because of legacy reasons.
If you execute this code in chrome
(function(){
'use strict';
return document.createElement('object')()
})()
you get undefined
as a return value. If you execute it in firefox you get an Exception
Component is not available" nsresult: "0x80040111 (NS_ERROR_NOT_AVAILABLE)" location: "JS frame :: debugger eval code :: :: line 1" data: no
Interestingly document.createElement('object') instanceof Function
is false
and thus none of the methods from Function.prototype
do exist on HTMLObjectElement
.
As stated in https://es5.github.io/x11.html#x11.4.3, HTMLObjectElement (HTMLEmbedElement as well) has a [[Call]]
internal property. typeof
inspects this property to return "function"
, which I agree is quite surprising at first.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With