Can a Javascript literal object fire events? - javascript

I have a Javascript object literal:
var Toolbar = {
init: function(toolbar) {
this.Bar = $(toolbar); // scope is Toolbar object literal
this.Bar.find('clearButton').click(function() {
this.trigger('clear'); // doesn't work!
this.Bar.trigger('clear'); // works!
}
}
Toolbar.init($('div.toolbar'));
Toolbar.bind('clear', function() { ... }); // doesn't work!
Toolbar.Bar.bind('clear', function() { ... }); // works!
I'd like to be able to trigger the clear event on the Toolbar object literal rather than the toolbar DOM object referenced in the literal. Is this possible, and if so, how would I do it?

This should work:
var Toolbar = {
init: function(toolbar) {
this.Bar = $(toolbar); // scope is Toolbar object literal
this.Bar.find('.clearButton').click($.proxy(function() {
$(this).trigger('clear'); // should work now
this.Bar.trigger('clear'); // still works
}, this));
}
};
Toolbar.init($('div.toolbar'));
$(Toolbar).bind('clear', function() {
console.log('Toolbar');
}); // should work now
Toolbar.Bar.bind('clear', function() {
console.log('Toolbar.Bar');
}); // still works
You need to maintain the this reference in the click function. I used $.proxy; some folks use var self = this;
Toolbar is not a jQuery object so it should be wrapped in $() to access jQuery's functions. Also wrap the this that refers to a Toolbar instance in the click function.

How about this? :
var Toolbar = {
init: function(toolbar) {
this.Bar = $(toolbar); // scope is Toolbar object literal
this.trigger =
function() { this.Bar.trigger.apply(this.Bar, arguments); };
this.bind = function() { this.Bar.bind.apply(this.Bar, arguments); };
this.Bar.find('clearButton').click(function() {
this.trigger('clear');
}
};
Toolbar.init();
Toolbar.bind('clear', function() { ... });
If you want, you can readily create a function to handle the wrapping; either of these, as you prefer:
function wrapperitize(wrapper, wrappee, method /*, more_methods...*/)
{
wrapper[method] = function() { wrappee[method].apply(wrappee, arguments); };
for(var i = 3; i < arguments.length; ++i)
wrapperitize(wrapper, wrappee, arguments[i]);
}
function wrapperitize(wrapper, wrappeeProp, method /*, more_methods...*/)
{
wrapper[method] = function()
{
wrapper[wrappeeProp][method].apply(wrapper[wrappeeProp], arguments);
};
for(var i = 3; i < arguments.length; ++i)
wrapperitize(wrapper, wrappeeProp, arguments[i]);
}
where the former would be called as wrapperitize(this, this.Bar, 'trigger', 'bind') and the latter as wrapperitize(this, 'Bar', 'trigger', 'bind') (the difference being that the former will make this into a wrapper for whatever this.Bar currently is, whereas the latter will make this into a wrapper for whatever this.Bar might ever become in the future.
(Note, by the way, the tiny bit of recursion. This is to avoid problematic variable capture, due to the way closures work in JavaScript.)

If you want to be able to call a method on the Toolbar object, you'll need to define it there. If you don't need to add very many of those methods this way, you can just define each of them in the Toolbar object itself:
var Toolbar = {
clear: function() { this.Bar.trigger('clear'); }
init: function(toolbar) {
this.Bar = $(toolbar); // scope is Toolbar object literal
this.Bar.find('clearButton').click(function() {
this.clear();
}
}
However, if you need to call very many of them this will quickly get ugly. If you really want to be able to call all of the methods available of the jquery object on the Toolbar object, you could try to loop through all of them with a for in loop and add them to the Toolbar object, but this would be tedious, annoying to read, inefficient, and potentially cause some bugs. I would just use $(toolbar) whenever you wanted to call a method on that object as it gets rid of all those disadvantages. :D

Related

Using Prototype with "Namespace" for existing object

I am looking to achieve something along the following.
HTMLSpanElement.prototype.testNS = {
_this: this,
testFunc: function() {
console.log(this.innerHTML) //undefined as expected as this is the testFunc object
},
testFunc2: function() {
console.log(this._this) //Window object
}
}
My goal is to add some helper functions directly to a span element in this case.
So, if I had the following:
<span>test</span>
I could find the span and call this code to return "test"
spanElement.testNS.testFunc()
I know that a function retains scope of it's parent when I do it like so...
HTMLSpanElement.prototype.testFunc = function() {
console.log(this.innerHTML)
}
But I am attempting to organize the code a bit and make it more obvious where the functions are coming from when I add them, and I can't seem to find a way to retain scope, when I do a normal JSON object grab the this scope into _this: this it just returns the global scope of "window".
Disclaimer: You shouldn't be trying to modify the prototypes on built-in types, especially host objects. It's a bad idea.
The reason your approach isn't working for you is that the functions are being called with the testNS object as the this.
You can get this to work if you define testNS as a property with a getter function, using Object.defineProperty. The reason this works is that the get function runs in the context of the object on which the property is being accessed (which would be the span):
Object.defineProperty(HTMLSpanElement.prototype, 'testNS', {
get: function() {
var _this = this;
return {
testFunc: function() {
console.log(_this.innerHTML)
},
testFunc2: function() {
console.log(_this)
}
}
}
});
var span = document.getElementById('mySpan');
span.testNS.testFunc();
span.testNS.testFunc2();
<span id="mySpan">Wah-hoo!</span>
A more "vanilla" approach is to just have testNS be a plain function and call it like one. This works because testNS is called in the context of the object on which it is being called (again, the span):
HTMLSpanElement.prototype.testNS = function() {
var _this = this;
return {
testFunc: function() {
console.log(_this.innerHTML)
},
testFunc2: function() {
console.log(_this)
}
}
}
var span = document.getElementById('mySpan');
span.testNS().testFunc();
span.testNS().testFunc2();
<span id="mySpan">Wah-hoo!</span>
When you call a function as foo.bar() then this inside bar refers to foo. Hence if you call the function as spanElement.testNS.testFunc(), this refers to spanElement.testNS.
_this: this, cannot work because this cannot refer to a <span> element.
To get access to spanElement from testFunc you could implement testNS as a getter:
Object.defineProperty(HTMLSpanElement.prototype, 'testNS', {
get: function() {
var element = this;
return {
testFunc: function() {
console.log(element.innerHTML);
},
};
},
});
document.querySelector('span').testNS.testFunc();
<span>foo</span>
Because it's a strange requirement I wrote a an equivalent strange solution :-)
Basically the createElement has been overriden in order to add a namespace object literal and then define a new function testFunc on top of the namespace using the instance of the element binded to the function
!function(){
var defaultNamespace = "testNS";
var createElement = document.createElement;
document.createElement = function(tag, namespace) {
var element = createElement.apply(document, arguments);
element[namespace || defaultNamespace] = {
testFunc : function() {
console.log(this.innerHTML);
}.bind(element)
};
return element;
}
}();
var span = document.createElement("span");

In JavaScript, inject my function into a library without changing function's properties

I need to inject my own function instead of the existing one, while keeping all of the original properties. So given this code:
var lib = {
func: function(foo) { return 1+foo; }
};
lib.func.bar = 10;
lib.func.bar2 = function() { return this(this.bar); };
// current behavior: lib.func.bar2() returns 11
// needed behavior: lib.func.bar2() to return 12, without changing bar2()
I need to replace the original func with my own version, while keeping all of its existing functionality intact:
var newFunc = function(foo) { return foo + 2; }
// copy the old lib.func.* to the newFunc
$.each(lib.func, function(k,v) { newFunc[k] = v; });
lib.func = newFunc;
The above seems to work, since when i call lib.func.bar2(), the result is 12, but this seems overly complex and potentially might cause other issues. What is the right way? Is there a way to bind the lib.func context to the newFunc somehow? or some other way?
You should assign the properties to the new function, not the old one:
$.each(obj.func, function(k,v) { newFunc[k] = v; });
If you want to alter what a function does when called, without creating a new different function, that would require altering the [[Code]] internal property, but most implementations don't expose it.
However, you can try this approach:
function code() {
return 123; /* Whatever */
}
function f() {
return code.apply(this, arguments); /* Redirect call to `code` */
}
f(); // 123
code = function() {
return 'abc'; /* Whatever else */
};
f(); // 'abc

Where/when to set function prototype?

I'm new to javascript prototypes.
In examples, prototypes are assigned in-line with the main program definition, but doing so has start-up sequence ramifications.
The following shows how I currently apply a prototype to a group of singletons. It would be nice to instead assign the prototype within the descendant class, or somewhere more visibly 'bound' to it, for clarity. (Note the panels are instantiated within the controller to enforce separation.)
Is there another location/method to accomplish this I'm overlooking? Also, am I violating any well-known styles with the current approach?
var controller = new Controller();
function Controller() {
var panels = {
search: SearchPanel,
results: ResultsPanel,
details: DetailsPanel,
action: ActionPanel,
};
$.each(panels, function (i, v) {
// THE QUESTION REFERS TO THIS FOLLOWING STATEMENT:
v.prototype = new PanelCommon();
panels[i] = new v();
});
this.publish = function (site, message) {
$.each(panels, function (i, v) {
if (v[site]) v[site](message);
});
}
/*...*/
}
function PanelCommon() { /*...*/ }
function SearchPanel() { /*...*/ }
function ResultsPanel() { /*...*/ }
function DetailsPanel() { /*...*/ }
function ActionPanel() { /*...*/ }
Another fit for the dynamic nature of JavaScript is the concept of Mixins or Augmentation, which are sometimes more natural than prototypical inheritance.
What do I mean by a mixin?
A "mixin" that takes an object, and injects more functionality. Basically, the idea is that we are going to take an object, and start adding behavior to it.
Consider the following mixinPanelTo() function. It'll be a function that takes a constructor and adds a common render() function to it's prototype.
var mixinPanelTo = (function() {
var render = function() {
// a render function that all panels share
console.log("rendering!")
}
// Augment
return function(cls) {
cls.prototype.render = render;
}
})();
Now that we have this, we can mix that functionality into any constructor we want:
var SearchPanel = function() {}
SearchPanel.prototype.search = function(query) {
/* search stuff */
this.render();
}
mixinPanelTo(SearchPanel)
Then, we should be able to
var panel = new SearchPanel()
panel.search("foo"); // "rendering!" on the console
Multiple mixins
One advantage of mixins over inheritance is a more granular control over applied functionality, and also the ability to borrow functionality from multiple parents
var mixinRender = function(cls) { /* inject render */ }
var mixinSearch = function(cls) { /* inject search */ }
var mixinInfiniteScroll = function(cls) { /* inject infinite scroll */ }
var customPanel = function() {}
mixinRender(customPanel);
mixinSearch(customPanel);
mixinInfiniteScroll(customPanel)
This would be difficult to accomplish with prototypical inheritance. Other than trying to make a bizarre class hierarchy.
Borrowing functionality
You can also have your mixin's require functionality/configuration from your target class. For instance, lets take mixinInfinitScroll
var mixinInfiniteScroll = function(cls, fetch) {
var page = 0;
cls.prototype.more = function() {
var data
// get more results
if(typeof fetch == "function")
data = fetch.call(this, ++page)
else
// assume a key in this
data = this[fetch](++page)
/* do work with data */
}
}
And then when mixing in this functionality, we can inject specific functionality:
// by key
var Panel1 = function() { }
Panel1.prototype.fetch = function() { /* go get more results */ }
mixinInifiniteScroll(Panel1, "fetch")
// or even with a direct reference
var Panel1 = function() { }
Panel1.prototype.fetch = function() { /* go get more results */ }
mixinInifiniteScroll(Panel1, Panel1.prototype.fetch)
// or even an anonymous function
var Panel1 = function() { }
mixinInifiniteScroll(Panel1, function() { /* go get more results */ })
Overriding methods
You can also override prototype methods in mixins, which makes them quite powerful
var augmentRender = function(cls, renderFn) {
var oldRender = cls.prototype[renderFn];
cls.prototype[renderFn] = function() {
/* prep */
oldRender.apply(this, arguments);
/* make some more changes */
}
}
And then we can say:
var Panel = function() { }
Panel.prototype.render = function() { /* my render */ }
augmentRender(Panel, "render")
Anyway, not that there is anything wrong with prototypical inheritance, but this might give you some more ideas of different ways to solve your problem by approaching it in a different way.
Usually prototypes are assigned immediately following the declaration of the constructor function. Also, don't forget to modify the constructor property of the newly instantiated prototype.
Sean also makes an interesting point about using Object.create, but whether or not you want to do that really depends on the contents of the PanelCommon constructor function. You also may have to shim Object.create in older browsers.
function PanelCommon() {}
function SearchPanel() {}
SearchPanel.prototype = new PanelCommon();
SearchPanel.prototype.constructor = SearchPanel;
function ResultsPanel() {}
ResultsPanel.prototype = new PanelCommon();
ResultsPanel.prototype.constructor = ResultsPanel;
function DetailsPanel() {}
DetailsPanel.prototype = new PanelCommon();
DetailsPanel.prototype.constructor = DetailsPanel;
function ActionPanel() {}
ActionPanel.prototype = new PanelCommon();
ActionPanel.prototype.constructor = ActionPanel;
You can use Object.create - that will avoid the new SuperClass weirdness of the ES3 solution:
> SearchPanel.prototype = Object.create(PanelCommon.prototype)
> SearchPanel.prototype.constructor = SearchPanel
> new SearchPanel instanceof PanelCommon
true
This can be extracted into a very simple extends function:
function extends(cls, superClass) {
cls.prototype = Object.create(superClass.prototype);
cls.prototype.constructor = cls;
return cls;
}
Which can then be used like this:
var SpecialPanel = extends(function SpecialPanel() {}, PanelCommon);

Crockford's Prototypical Inheritance - Usage

I've been building a small JS framework for use at my job, and I'd like to employ Douglas Crockford's prototypical inheritance patterns. I think I get the general idea of how the prototype object works, but what isn't clear is the way in which I would use this pattern beyond the simplest example.
I'll flesh it out to the point that I understand it.
(function () {
'use strict';
var Vehicles = {};
Vehicles.Vehicle = function () {
this.go = function () {
//go forwards
};
this.stop = function () {
//stop
};
};
Vehicles.Airplane = Object.create(Vehicles.Vehicle());
}());
So now my Vehicles.Airplane object can go() and stop(), but I want more. I want to add takeOff() and land() methods to this object. I could just use ugly dot notation afterwards:
Vehicles.Airplane.takeOff = function () {
//take off stuff
}
But that seems wrong, especially if I were to add many methods or properties. The question asked at here seems to be very similar to mine, but the answer doesn't quite ring true for me. The answer suggests that I should build an object literal before using Object.create, and that I should pass that object literal into the create method. In the example code given, however, it looks like their new object inherits nothing at all now.
What I'm hoping for is some syntax similar to:
Vehicles.Airplane = Object.create(Vehicles.Vehicle({
this.takeOff = function () {
//takeOff stuff
};
this.land = function () {
//land stuff
};
}));
I know this syntax will break terribly with Object.create right now, because of course I'm passing Vehicle.Vehicle a function rather than an object literal. That's beside the point. I'm wondering in what way I should build new properties into an object that inherits from another without having to list them out one at a time with dot notation after the fact.
EDIT:
Bergi, after some anguished thought on the topic, I think I really want to go with what you described as the "Classical Pattern". Here is my first stab at it (now with actual code snippets rather than mocked up hypotheticals - You even get to see my crappy method stubs):
CS.Button = function (o) {
o = o || {};
function init(self) {
self.domNode = dce('a');
self.text = o.text || '';
self.displayType = 'inline-block';
self.disabled = o.disabled || false;
self.domNode.appendChild(ctn(self.text));
if (o.handler) {
self.addListener('click', function () {
o.handler(self);
});
}
}
this.setText = function (newText) {
if (this.domNode.firstChild) {
this.domNode.removeChild(this.domNode.firstChild);
}
this.domNode.appendChild(ctn(newText));
};
init(this);
};
CS.Button.prototype = Object.create(CS.Displayable.prototype, {
constructor: {value: CS.Button, configurable: true}
});
CS.Displayable = function (o) { // o = CS Object
o = o || {};
var f = Object.create(new CS.Element(o));
function init(self) {
if (!self.domAnchor) {
self.domAnchor = self.domNode;
}
if (self.renderTo) {
self.renderTo.appendChild(self.domAnchor);
}
}
//Public Methods
this.addClass = function (newClass) {
if (typeof newClass === 'string') {
this.domNode.className += ' ' + newClass;
}
};
this.addListener = function (event, func, capture) {
if (this.domNode.addEventListener) {
this.domNode.addEventListener(event, func, capture);
} else if (this.domNode.attachEvent) {
this.domNode.attachEvent('on' + event, func);
}
};
this.blur = function () {
this.domNode.blur();
};
this.disable = function () {
this.disabled = true;
};
this.enable = function () {
this.disabled = false;
};
this.focus = function () {
this.domNode.focus();
};
this.getHeight = function () {
return this.domNode.offsetHeight;
};
this.getWidth = function () {
return this.domNode.offsetWidth;
};
this.hide = function () {
this.domNode.style.display = 'none';
};
this.isDisabled = function () {
return this.disabled;
};
this.removeClass = function (classToRemove) {
var classArray = this.domNode.className.split(' ');
classArray.splice(classArray.indexOf(classToRemove), 1);
this.domNode.className = classArray.join(' ');
};
this.removeListener = function () {
//Remove DOM element listener
};
this.show = function () {
this.domNode.style.display = this.displayType;
};
init(this);
};
CS.Displayable.prototype = Object.create(CS.Element.prototype, {
constructor: {value: CS.Displayable, configurable: true}
});
I should be quite clear and say that it's not quite working yet, but mostly I'd like your opinion on whether I'm even on the right track. You mentioned "instance-specific properties and methods" in a comment in your example. Does that mean that my this.setText method and others are wrongly placed, and won't be available to descendant items on the prototype chain?
Also, when used, it seems that the order of declaration now matters (I can't access CS.Displayable.prototype, because (I think) CS.Button is listed first, and CS.Displayable is undefined at the time that I'm trying to reference it). Is that something I'll just have to man up and deal with (put things in order of ancestry in the code rather than my OCD alphabetical order) or is there something I'm overlooking there as well?
Vehicles.Airplane = Object.create(Vehicles.Vehicle());
That line is wrong. You seem to want to use new Vehicles.Vehicle - never call a constructor without new!
Still, I'm not sure which pattern you want to use. Two are coming to my mind:
Classical Pattern
You are using constructor functions just as in standard JS. Inheritance is done by inheriting the prototype objects from each other, and applying the parent constructor on child instances. Your code should then look like this:
Vehicles.Vehicle = function () {
// instance-specific properties and methods,
// initialising
}
Vehicles.Vehicle.prototype.go = function () {
//go forwards
};
Vehicles.Vehicle.prototype.stop = function () {
//stop
};
Vehicles.Airplane = function() {
// Vehicles.Vehicle.apply(this, arguments);
// not needed here as "Vehicle" is empty
// maybe airplane-spefic instance initialisation
}
Vehicles.Airplane.prototype = Object.create(Vehicles.Vehicle.prototype, {
constructor: {value:Vehicles.Airplane, configurable:true}
}); // inheriting from Vehicle prototype, and overwriting constructor property
Vehicles.Airplane.prototype.takeOff = function () {
//take off stuff
};
// usage:
var airplane = new Vehicles.Airplace(params);
Pure Prototypical Pattern
You are using plain objects instead of constructor functions - no initialisation. To create instances, and to set up inheritance, only Object.create is used. It is like having only the prototype objects, and empty constructors. instancof does not work here. The code would look like this:
Vehicles.Vehicle = {
go: function () {
//go forwards
},
stop: function () {
//stop
}
}; // just an object literal
Vehicles.Airplane = Object.create(Vehicles.Vehicle); // a new object inheriting the go & stop methods
Vehicles.Airplane.takeOff = function () {
//take off stuff
};
// usage:
var airplane = Object.create(Vehicles.Airplane);
airplane.prop = params; // maybe also an "init" function, but that seems weird to me
You got Object.create wrong. The first argument should be an object (maybe that's why people suggested you pass a literal).
In your first example, you're actually passing undefined:
Vehicles.Airplane = Object.create(Vehicles.Vehicle()); // the function call will
// return undefined
The following would work, but it's not very Crockford-ish:
Vehicles.Airplane = Object.create(new Vehicles.Vehicle());
The way I believe Crockford would do it (or, at least, wouldn't complain of):
var Vehicles = {};
Vehicles.Vehicle = {
go : function() {
// go stuff
},
stop : function() {
// go stuff
}
};
Vehicles.Airplane = Object.create(Vehicles.Vehicle, {
takeOff : {
value : function() {
// take-off stuff
}
},
land : {
value: function() {
// land stuff
}
}
});
Note that Vehicles.Vehicle is just a literal, which will be used as the prototype for other objects. When we call Object.create, we pass Vehicles.Vehicle as the prototype, and takeOff and land will be own properties of Vehicles.Airplane. You may then call Object.create again, passing Vehicles.Airplane as the prototype, if you want to create e.g. a Boeing.
The own properties passed as the second parameter are packed in an object that contains a representation of their property descriptors. The outer keys are the names of your properties/methods, and each one points to another object containing the actual implementation as the value. You may also include other keys like enumerable; if you don't they'll take the default values. You can read more about descriptors on the MDN page about Object.defineProperty.

JS Object this.method() breaks via jQuery

I'm sure there's a simple answer to this, but it's Friday afternoon and I'm tired. :(
Not sure how to explain it, so I'll just go ahead and post example code...
Here is a simple object:
var Bob =
{ Stuff : ''
, init : function()
{
this.Stuff = arguments[0]
}
, doSomething : function()
{
console.log( this.Stuff );
}
}
And here it is being used:
$j = jQuery.noConflict();
$j(document).ready( init );
function init()
{
Bob.init('hello');
Bob.doSomething();
$j('#MyButton').click( Bob.doSomething );
}
Everything works, except for the last line. When jQuery calls the doSomething method it is overriding 'this' and stopping it from working.
Trying to use just Stuff doesn't work either.
So how do I refer to an object's own properties in a way that allows jQuery to call it, and also allows the object to work with the calling jQuery object?
i.e. I would like to be able to do things like this:
doSomething : function()
{
console.log( <CurrentObject>.Stuff + $j(<CallerElement>).attr('id') );
}
(Where <CurrentObject> and <CallerElement> are replaced with appropriate names.)
This is not jQuery's fault, it is integral to the way JavaScript handles objects.
Unlike in most other object-oriented languages, ‘this’ is not bound on a per-method level in JavaScript; instead, it's determined purely by how the function is called:
Bob= {
toString: function() { return 'Bob!'; },
foo: function() { alert(this); }
};
Brian= {
toString: function() { return 'Brian!'; },
};
Bob.foo(); // Bob!
Bob['foo'](); // Bob!
Brian.foo= Bob.foo;
Brian.foo(); // Brian! NOT Bob
var fn= Bob.foo;
fn(); // window NOT Bob
What you are doing in the case of:
$j('#MyButton').click( Bob.doSomething );
is like the last example with fn: you are pulling the function doSomething off Bob and passing it to jQuery's event handler setter as a pure function: it no longer has any connection to Bob or any other object, so JavaScript passes in the global window object instead. (This is one of JavaScript's worst design features, as you might not immediately notice that window isn't Bob, and start accessing properties on it, causing weird and confusing interactions and errors.)
To remember Bob, you generally make a function as in nickyt's answer, to keep a copy of ‘Bob’ in a closure so it can be remembered at callback time and used to call the real method. However there is now a standardised way of doing that in ECMAScript Fifth Edition:
$j('#MyButton').click( Bob.doSomething.bind(Bob) );
(You can also put extra arguments in the bind call to call doSomething back with them, which is handy.)
For browsers that don't yet support Fifth Edition's bind() method natively (which, at this point, is most of them), you can hack in your own implementation of bind (the Prototype library also does this), something like:
if (!Object.bind) {
Function.prototype.bind= function(owner) {
var that= this;
var args= Array.prototype.slice.call(arguments, 1);
return function() {
return that.apply(owner,
args.length===0? arguments : arguments.length===0? args :
args.concat(Array.prototype.slice.call(arguments, 0))
);
};
};
}
Change
$('#MyButton').click( Bob.doSomething );
to
$('#MyButton').click( function() { Bob.doSomething() } );
You could also add to your Bob object a private field var that = this and use that everywhere in members instead of this if you really want to avoid the anonymous function.
e.g.
var Bob = new function() {
// Private Fields
var that = this;
// Public Members
this.Stuff = '';
this.init = function() {
that.Stuff = arguments[0];
}
this.doSomething = function() {
console.log( that.Stuff );
}
}
The identity of this is a common problem in javascript. It would also break if you tried to create a shortcut to doSomething:
var do = Bob.doSomething;
do(); // this is no longer pointing to Bob!
It's good practice to not rely on the identity of this. You can do that in a variety of ways, but the easiest is to explicitly reference Bob instead of this inside of doSomething. Another is to use a constructor function (but then you lose the cool object-literal syntax):
var createBob = function() {
var that = {};
that.Stuff = '';
that.init = function() {
that.Stuff = arguments[0];
};
that.doSomething = function() {
console.log( that.Stuff );
};
return that;
}
var bob = createBob();
You could always try doing something like this:
$j('#MyButton').click(function(event) {
Bob.doSomething(event, this);
});
Now doSomething will still have Bob for its this, and using the function arguments, it will have the event object, and the element it was triggered on.

Categories

Resources