Calling the Object.prototype Method Globally

This code is causing an error.

try { alert(hasOwnProperty('window')); } catch(e) { alert(e); // Type Error : can't convert undefined to object } 

but this code does not throw an error.

 try { alert(this.hasOwnProperty('window')); // true (if on browser) } catch(e) { // through catch block alert(e); } 

Live Example | Live source

As for kwon, func(arg) equals this.func(arg) if this is a global object. Why is this happening?

+7
javascript
source share
2 answers

I think what happens is that we have the interaction of a strict mode code and a non-strict mode. And in fact, when I dug up a copy of Firefox 3.6.15 (which does not support strict mode), I don’t get the error using the link I sent to your question (it warns β€œtrue” twice).

The code you provided is obviously a non-strict mode code. But what about the implementation of the hasOwnProperty browser? I suspect that this is strict, in browsers where strict mode is supported.

When you speak

 func(); 

... what the browser does looks func using standard identifier resolution, and then calls it as if you did this:

 func.call(undefined); 

If func is a free function, then in a call to func , this is a global object. But , if func is a strict mode function, this inside the call is undefined .

In contrast to this:

 this.func(); 

... he looks up func again (this time by resolving the property using the prototype chain), and then effectively does this:

 this.func.call(this); 

In strict or free mode, this means that this inside the function will be this . (And of course, globally, this is a global object.)

Here is an example of this interaction using code that we can see, not hasOwnProperty :

 (function() { "use strict"; window.strictFunction = function() { display("strictFunction: this === window? " + (this === window)); display("strictFunction: typeof this: " + typeof this); }; })(); strictFunction(); strictFunction.call(undefined); 

As you can see, this free code, with the exception of a bit, defines the strictFunction function on window . Then we call this function twice from the empty code. The result is the following:

  strictFunction: this === window?  false
 strictFunction: typeof this: undefined
 strictFunction: this === window?  false
 strictFunction: typeof this: undefined 

In contrast, if we do this with a free function, the result is:

  looseFunction: this === window?  true
 looseFunction: typeof this: object
 looseFunction: this === window?  true
 looseFunction: typeof this: object 

Full example: Live Copy | Live source

 <!DOCTYPE html> <html> <head> <meta charset=utf-8 /> <title>Fun With Strict Interactions</title> <style> body { font-family: sans-serif; } p { margin: 0; } </style> </head> <body> <script> (function() { "use strict"; window.strictFunction = function() { display("strictFunction: this === window? " + (this === window)); display("strictFunction: typeof this: " + typeof this); }; })(); (function() { window.looseFunction = function() { display("looseFunction: this === window? " + (this === window)); display("looseFunction: typeof this: " + typeof this); }; })(); display("Direct call:"); strictFunction(); looseFunction(); display("<hr>Call with <code>.call(undefined)</code>:"); strictFunction.call(undefined); looseFunction.call(undefined); display("<hr>Call with <code>.call(window)</code>:"); strictFunction.call(window); looseFunction.call(window); function display(msg) { var p = document.createElement('p'); p.innerHTML = String(msg); document.body.appendChild(p); } </script> </body> </html> 

Exit (using JavaScript engine that supports strict mode):

  Direct call:
 strictFunction: this === window?  false
 strictFunction: typeof this: undefined
 looseFunction: this === window?  true
 looseFunction: typeof this: object
 -
 Call with .call (undefined):
 strictFunction: this === window?  false
 strictFunction: typeof this: undefined
 looseFunction: this === window?  true
 looseFunction: typeof this: object
 -
 Call with .call (window):
 strictFunction: this === window?  true
 strictFunction: typeof this: object
 looseFunction: this === window?  true
 looseFunction: typeof this: object 
+8
source share

The problem is one of the contexts. That is, essentially, the value of this inside the function when it was called.

The hasOwnProperty('window') call has no context. This is the same as doing this:

 hasOwnProperty.call(undefined, 'window'); 

While this.hasOwnProperty('window') same as this:

 hasOwnProperty.call(this, 'window'); 

The second line of code will have the expected result ( true ), but the first will obviously not work.

+1
source share

All Articles