Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why type of <object> is a function?

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?

like image 423
Denis L Avatar asked Jun 06 '16 12:06

Denis L


People also ask

What type of object is a function?

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.

Why type of object is function in JavaScript?

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.

How is object a function?

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.

Is every object a function?

Object is a function, but not every object is a function.


2 Answers

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.

like image 198
Till Arnold Avatar answered Oct 10 '22 00:10

Till Arnold


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.

like image 29
Delapouite Avatar answered Oct 10 '22 00:10

Delapouite