Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
268 views
in Technique[技术] by (71.8m points)

If JavaScript has first-class functions, why doesn’t calling this function in a variable work?

JavaScript is purported to have first-class functions, so this seems like the following ought to work:

var f = document.getElementById;
var x = f('x');

But it fails on all browsers, with a different cryptic error message on each one. Safari says “Type error”. Chrome says “Illegal invocation”. Firefox says “Could not convert JavaScript argument”.

Why?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

When you call obj.method() in Javascript the method is passed obj as this. Calling document.getElementById('x') with therefore set this to document.

However if you just write f = document.getElementById you now have a new reference to the function, but that reference is no longer "bound" to document.

So your code doesn't work because when you call f as a bare function name it ends up bound to the global object (window). As soon as the innards of the function try to use this it finds that it now has a window instead of a document and unsurprisingly it doesn't like it.

You can make f work if you call it so:

var x = f.call(document, 'x');

which calls f but explicitly sets the context to document.

The others way to fix this is to use Function.bind() which is available in ES5 and above:

var f = document.getElementById.bind(document);

and is really just a generalised short cut for creating your own wrapper that correctly sets the context:

function f(id) {
    return document.getElementById(id);
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...