Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I directly assign document.getElementById to a different function?

Tags:

javascript

So I'm trying to define a function g() that is like document.getElementById. The following works just fine:

var g = function(id){return document.getElementById(id)};

But why doesn't this more direct code work?

var g = document.getElementById;
like image 724
zjmiller Avatar asked Jun 11 '11 21:06

zjmiller


People also ask

How do I fix document getElementById is not a function?

To solve the "getElementById is not a function" error, make sure to spell the getElementById() method correctly, as it is case-sensitive, and only call the method on the document object, e.g. document. getElementById('btn') . Copied!

What can I use instead of document getElementById?

A commonly-used alternative to document. getElementById is using a jQuery selector which you read about more here.

Is document getElementById a function?

The getElementById() is a DOM method used to return the element that has the ID attribute with the specified value. This is one of the most common methods in the HTML DOM and is used almost every time we want to manipulate an element on our document. This method returns null if no elements with the specified ID exists.


2 Answers

The problem is that of context. When you fire an object's function, it is fired with the object as the value of this (unless you specify otherwise). g = document.getElementById puts the function getElementById into the variable g, but doesn't set the context.

Therefore, when you run g(someId), there is no context on which the function can run. It is run with the global object window as the value of this, and that doesn't work. (To be precise, it doesn't work because you could be operating with any document object, not just window.document, and you haven't specified one.)

You could get around this with call, where you set the context:

g.call(document, someId);

However, this isn't an improvement over the original!

like image 150
lonesomeday Avatar answered Oct 08 '22 02:10

lonesomeday


As lonesomeday's answer already shows, the problem is with the execution context. I would like to add that there is a way to create a function with the execution context. Open your browser's Developer Tools for this page and try the following in the Console:

> document.getElementById('notify-container');
// <div id="notify-container"></div>

> var _d = document.getElementById;
// undefined

> _d
// ƒ getElementById() { [native code] }

> _d('notify-container');
// Uncaught TypeError: Illegal invocation
//     at <anonymous>:1:1

As before, directly invoking the variable _d which is assigned to document.getElementById fails. But you can use Function.prototype.bind to bind the execution context.

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

> var d = document.getElementById.bind(document);
// undefined

> d('notify-container');
// <div id="notify-container"></div>

You also do not have to worry much about browser compatibility if you want to use bind: See https://caniuse.com/#feat=es5.

like image 32
sampathsris Avatar answered Oct 08 '22 02:10

sampathsris