admin管理员组文章数量:1333390
In Internet Explorer 8 (works also in IE9 in IE7/8 modes) the following code alerts object
and undefined
instead of expected function
and something like function() { [native code] }
.
alert("typeof window.setTimeout = " + typeof window.setTimeout); // object
alert("window.setTimeout.apply = " + window.setTimeout.apply ); // undefined
Try it: /
Why is this happening? What would be a workaround to get the actual setTimeout
?
Update
I am trying to create a wrapper around setTimeout
:
var _oldSetTimeout = window.setTimeout;
window.setTimeout = function ()
{
// ...
return _oldSetTimeout.apply(this, arguments); // this is place where IE 7/8 says 'Object doesn't support this property or method'
// and _oldSetTimeout looks like an empty object
};
In Internet Explorer 8 (works also in IE9 in IE7/8 modes) the following code alerts object
and undefined
instead of expected function
and something like function() { [native code] }
.
alert("typeof window.setTimeout = " + typeof window.setTimeout); // object
alert("window.setTimeout.apply = " + window.setTimeout.apply ); // undefined
Try it: http://jsfiddle/BsvZw/5/
Why is this happening? What would be a workaround to get the actual setTimeout
?
Update
I am trying to create a wrapper around setTimeout
:
var _oldSetTimeout = window.setTimeout;
window.setTimeout = function ()
{
// ...
return _oldSetTimeout.apply(this, arguments); // this is place where IE 7/8 says 'Object doesn't support this property or method'
// and _oldSetTimeout looks like an empty object
};
Share
Improve this question
edited Jul 23, 2012 at 20:26
Loki Kriasus
asked Jul 23, 2012 at 20:14
Loki KriasusLoki Kriasus
1,30110 silver badges24 bronze badges
5
- what are you trying to acplish? – Ibu Commented Jul 23, 2012 at 20:17
- Do you need this to stop the setTimeout? – davidbuzatto Commented Jul 23, 2012 at 20:19
- @lbu, I am trying to replace setTimeout with a wrapper. I'll update the question. – Loki Kriasus Commented Jul 23, 2012 at 20:21
- 1 @Alfabravo: apply is cross browser. The problem is that some "functions" are not actually functions in IE. – hugomg Commented Jul 23, 2012 at 20:41
- @missingno Well, I just checked out IE docs but I'll stand corrected :) – Alfabravo Commented Jul 23, 2012 at 20:43
2 Answers
Reset to default 9Why is this happening?
Basically, because IE hates web developers and is messing with you.
More seriously, things provided by the browser implementation that are not part of the core Javascript language may be classified as host objects. When it es to host objects all bets are off and they are basically allowed to do anything they want[1] without needing to respect usual Javascript semantics.
What would be a workaround to get the actual setTimeout?
I know its really ugly, but you could do an if-else-if chain up to a predefined number of arguments. In setTimeout's case this shouldn't be a big problem since you shouldn't ever need more then 2 or 3 arguments for it.
var _oldSetTimeout = window.setTimeout;
window.setTimeout = function (a1, a2, a3)
{
switch(arguments.length){
case 0: return _oldSetTimeout();
case 1: return _oldSetTimeout(a1);
case 2: return _oldSetTimeout(a1, a2);
default: return _oldSetTimeout(a1, a2, a3);
}
};
While this is a very ugly solution, sometimes its the only way. For example, there is no way to invoke constructors with variadic arguments either.
[1] To give you an idea of how evil host objects can be, the other day I had to do feature detection for XPath methods in DOM nodes/documents. Instead of the usual if(node.selectNodes)
test I had to use if("selectNodes" in node)
because nodes are host objects in in IE and just accessing the selectNodes property would actually call it, giving me an "incorrect number of arguments" exception!
When you call "apply" on a function, the function object itself is the "this" of the call to "apply", so you can do this:
function test(s) { alert(""+s); }
Function.prototype.apply.call(setTimeout, null, [test, 0, 'abc']);
// Note: same as "setTimeout.apply(null, [test, 0, 'abc']);" in supported browsers.
Basically, we are forcing the use of Function.prototype.apply
instead of trying to look for a non-existing setTimeout.apply
. In the parameters to call
, the first argument is the function we want to run using apply
(the object context, which is setTimeout
in this case). What follows next are the parameters that get pass to apply
, the first of which is the expect this
the function will be run under ('null' in this case, since setTimeout
does not allow a this
context value), and the following being the array of arguments to be passed to the function we want to run.
This works in IE7+, except IE7 doesn't pass on the custom parameters (i.e 'abc' in this example, which will prompt "undefined" instead).
Here's a TypeScript implementation:
/** Helps support cases where 'apply' is missing for a host function object (i.e. IE7 'setTimeout', etc.). This function
* will attempt to call '.apply()' on the specified function, and fall back to a work around if missing.
* @param {Function} func The function to call '.apply()' on.
* @param {Object} _this The calling object, which is the 'this' reference in the called function (the 'func' argument).
* Note: This must be null for special host functions, such as 'setTimeout' in IE7.
* @param {any} args The arguments to apply to given function reference (the 'func' argument).
*/
function apply(func: Function, _this: Object, args: any[]): any {
if (func.apply) {
return func.apply(_this, args);
} else {
return Function.prototype.apply.call(func, _this, args);
}
}
... and a basic JavaScript one:
function apply(func, _this, args) {
if (func.apply) {
return func.apply(_this, args);
} else {
return Function.prototype.apply.call(func, _this, args);
}
}
本文标签: javascriptInternet Explorer 78 and window functions are empty objectsStack Overflow
版权声明:本文标题:javascript - Internet Explorer 78 and window functions are empty objects - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742333260a2455116.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论