Jump to content

understanding jQuery's expose / JS scoping problem


skaterdav85

Recommended Posts

Im trying to understand jQuery's approach by creating a constructor function (i.e jQuery) within a self executing anonymous function, and exposing it to the global window object. I wrote a constructor function (myLib), but for some reason it it throws an error in IE and I have no idea why. The error says "undefined is null or not an object". It does work in IE if I use the new operator which i wrote in my comment, but when you dont use it, I get the error. I have some scoping issue but I can't figure out how to fix it.Here is my code:

<script>(function(){var myLib = function (selector) {	if(this == window) {		return new window.myLib(selector);	}	};myLib.prototype.wussup = function () {	alert('sup');	};//expose myLib to the global window objectwindow.myLib = myLib;})();//works fine//(new myLib('.someclass')).wussup();//doesn't work in IEmyLib('.someclass').wussup();</script>

Link to comment
Share on other sites

hmm, I've never thought of prototyping window or document. from what I've gathered, anything in this convention

(function(){});

automatically scopes to the global scope. i.e. this == global scope.typically (and I can't really vouch for jQuery's implementation) I have been in the practice of defining my own namespace and using that for my scripts and attaching everything to that. it seems a little cleaner to me.

w3 = {};(function(_){  if(typeof _ === 'undefined'){	_ = this;  };  var Lib = function(user){	this.user = user;  };  Lib.prototype = {	wassup : function(){	  alert('sup '  + this.user + '?');	}  };  _.libInstance = new Lib('big dave');})(w3);

Link to comment
Share on other sites

You can also use the function.call method as a shortcut to that. The call method tells it what scope to run the code in, so this is automatically set.

w3 = {};(function(){  var Lib = function(user){	this.user = user;  };  Lib.prototype = {	wassup : function(){	  alert('sup '  + this.user + '?');	}  };  _.libInstance = new Lib('big dave');}).call(w3);

Link to comment
Share on other sites

automatically scopes to the global scope. i.e. this == global scope.
ya i do know that this points to the window object when inside a function that is invoked as a regular function. What I don't understand is why I have to say this.window === window instead of this === window in IE to see how the function was invoked and making sure it is called as a function constructor. Any speculation on that?
Link to comment
Share on other sites

It would be interesting to send this to the console and inspect, so you can see what the properties and things on it are. You can open IE's developer tools with F12 to get to the console, and use console.log to send things there. You could also put a breakpoint in your function so that you could inspect the local variables to check them out while execution is paused. If this is not the window object, it would be interesting to see what it is.

Link to comment
Share on other sites

I revised my code to the following:

(function(){	var myLib = function (selector) {		console.log(this);		if(this == window) {			return new window.myLib(selector);		}		};	myLib.prototype.wussup = function () {		alert('sup');		};	//expose myLib to the global window object	window.myLib = myLib;})();myLib('.someclass');

When I invoke myLib in FF, it first logs the Window and then logs an object (an instance of myLib) as you'd expect.When I invoke myLib in IE, it only logs the Window. When I view the properties of Window, myLib is a property, but the Window also has another property called 'window' which also has a property of myLib. Anyone have any insight into this?

Link to comment
Share on other sites

Well I have found the answer. Apparently IE's implementation of window is a bit different than other browsers. Using the firebug lite console in IE, you get the following results for each expression:In IE:

this === window; //false. True in Chrome's consolethis == window; //false. True in Chrome's consolethis.window == window; //truewindow.window == window; //truewindow.window === window; //false. True in Chrome's console

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...