4

OK, I looked a lot for this on the web but cannot find an answer.

I can expect CSS differences between browsers but there are JavaScript differences too?

So why this works in IE8:

window.print(); // works

but when I pass window.print to a function and call it, it don't work in IE8 (works in IE9):

function callIt(f){
    f.call();
};



callIt(window.print);

Is it a known issue?


EDIT

OK it does not work means it will simply ignore it, no javascript error or anything.

Sorry it gives this error:

   Object doesn't support this property or method

EDIT 2

I need to use call or apply since I need to pass the context. I am trying to create a class which I can pass functions and it can call it with the possibility of passing context or arguments. Do not tell me to use f() that is not an answer since it does not fix my problem. The question is on call and apply.

Aliostad
  • 80,612
  • 21
  • 160
  • 208
  • What behavior do you see? is there an error in the error console? – Sean McMillan Jul 29 '11 at 13:32
  • Maby I misunderstood you but yes, there are A LOT of cross-browser differences in javascript. Check this thread: http://stackoverflow.com/questions/565641/what-cross-browser-issues-have-you-faced or google for more. That is why JS frameworks like jQuery are so popular ) – XzKto Jul 29 '11 at 13:35
  • It gives me a javascript error in IE8 "Object doesn't support this property or method" – James Montagne Jul 29 '11 at 13:42
  • Exactly! In my actual code, it gives me that but using this, it was not. – Aliostad Jul 29 '11 at 13:59
  • @Aliostad @XzKto This is not a JavaScript difference. The ECMAScript specification does not cover the behavior of host objects (which `window` and `print` are). A browser can arbitrarily define the behavior of its host objects - JavaScript (the language) is not related to that. This is an issue with the object model of IE, not a JavaScript issue. – Šime Vidas Jul 29 '11 at 14:07
  • @Šime Vidas: You are most likely right. But I remember doing similar things with other objects in IE, I don't have any IE's avaliable now, but tested on ies4linux and it works with custom made objects. So, it seems that it is window-object related error. – XzKto Jul 29 '11 at 14:33
  • This is not the DOM stuff, it is passing a function as argument and then calling `call` or `apply` – Aliostad Jul 29 '11 at 15:05
  • 1) See Richard Hoffman's answer, and 2) what context would you be calling `window.print` in if not its window? I'm just curious, because I don't think `window.print` will work on anything other than a window object. So if you have a different `window` object, and you can use that as context, can´t you also just do `otherWindow.print()`? I just don't see the point of it all. Also, to answer your very first question: Yes, you can expect JS differences between browsers too (especially IE versions) :) – Flambino Jul 29 '11 at 15:42
  • @Flambino this is supposed to be a **generic solution that can call functions passed to it with a delay**. It does not work for `window.print`. – Aliostad Jul 29 '11 at 15:46
  • @Aliostad: Ok, you didn't mention the part about the delay before now – Flambino Jul 29 '11 at 15:53

3 Answers3

10

It seems window.* functions are separate types than user-created functions in IE < 9. Thus, they don't get any of the Function.prototype.*. You'll see that

typeof alert === 'object'

function a(){}

typeof a === 'function'

This would happen for any of the window.* functions. Only for IE < 9. WTG Miscrosoft.

However you can try

Function.prototype.call.call(window.print)

See if that works for you.

Richard Hoffman
  • 729
  • 3
  • 10
  • 1
    You are absolutely right. i also noticed it when checking their type and `typeof` was printing object and there was no constructor. **This is against ECMAScript standards.** – Aliostad Jul 29 '11 at 16:05
  • 1
    `window` and its properties are "host objects", and host objects are allowed to break the rules. (I don't like it, but that's now it is.) – Sean McMillan Jul 29 '11 at 17:08
2
    function callIt(f) {
        if (f) f();
    }

    callIt(window.print);

Done, no?


Update

per the poster's request that I answer the question, not recommend a solution that works, here she goes:

If you view typeof(window.print) in IE, you'll see that it reports itself as type object. Type object has no apply or call method. In my opinion, your design is wrong for the task. HOWEVER, if what you want is a rabbit hole to follow, here's the top:

var p = window.print;
window.print = function() { p(); }

function callIt(f){
     f.call();
}

callIt(window.print);

I have no idea what will happen in any other browser or how many procedural exceptions you'll have to make to account for it everywhere you'll need to.

Aliostad
  • 80,612
  • 21
  • 160
  • 208
Brian
  • 2,772
  • 15
  • 12
  • 1
    No. I need to use `.call` to be able to specify the `this`. – Aliostad Jul 29 '11 at 15:04
  • @Aliostad - I suppose the question is, why must you invoke the print method using .call? You could wrap window.print in a method, as suggested by Sean's posting below - callIt(function() { window.print(); }); – Brian Jul 29 '11 at 15:08
  • I have updated the question. Answer the question if you can please, question is clear: error on `call` or `apply`. – Aliostad Jul 29 '11 at 15:12
  • @Aliostad - updated and answered, though I urge you to reconsider your approach. – Brian Jul 29 '11 at 15:39
  • I had tried that. In that case it does not do anything. No errors. – Aliostad Jul 29 '11 at 15:45
  • @Aliostad - does nothing where? IE9? Or in all browsers you've mentioned? I'm getting a print dialog in IE7/IE8/FFX3.5.19... – Brian Jul 29 '11 at 15:55
  • @Brian let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/1957/discussion-between-aliostad-and-brian) – Aliostad Jul 29 '11 at 15:56
1

You almost certainly should not be using .call() here. f() will call the method, while f.call() will call it with an unset this. Under es3 (but not es5 strict,) an undefined value for this will be coerced to window. I suspect that IE9 properly handles this, while IE8 does not, but that's just a guess based on behavior.

If print cares about the value of this, you should call it as window.print() in order for this to be set correctly. In that case, you may have to wrap it in an anonymous function so that print doesn't get "sliced off" of window. callIt(function() { window.print();});

Sean McMillan
  • 10,058
  • 6
  • 55
  • 65