BackboneJS - using keyword this inside view - javascript

If i want to call a function inside Backbone view, i have to call it like this.
this.functionName()
If i want to call the same function inside forEach Or jquery's each function, this refers to different context here. So i need to hold view's reference to some other variable and i have to use it something like below.
refresh: function () {
var view = this;
$("#list").each (function () {
view.functionName();
})
}
And finally, if i look at my view, i declare like this almost all of my functions. Did anyone find better alternative for this?

Since you are using Backbone, you would already have underscore. Using underscore you can specify context for each call.
refresh: function() {
_.each($("#list"), function() {
this.functionName()
}, this))
}

This is indeed common in Javascript, by convention they call the variable that:
var that = this
jQuery also has a proxy() function which will call a function and set the context variable (this) to something you assign: http://api.jquery.com/jQuery.proxy/
So you could do something like this:
refresh: function() {
$("#list").each($.proxy(function() {
view.functionName()
}, this))
}
But most of the times it is even more unreadable. To be honest I never use proxy() and I can't think of a good example of when to use it, but it's nice to know of it's existance, might you ever need it.

The usuals are defining either var that = this; or var self = this; or var _this = this;
The Airbnb JavaScript Style Guide which I find very sane advocates the latter. (you may want to scroll a little to find the meat).

Related

Access parent property inside object literal

We have a JS framework that lets us set up "modules". Each module is added by calling the addModule method and passing a literal object that contains required properties about the module as well as optional methods. Example:
framework.addModule({
id: "test-module",
init: function () {
//stuff to do when initializing like set up jQuery bindings
$("div").click(function () {
// need access to literal object so I can call:
something.utility1();
});
},
utility1: function () {
something.utility2();
},
utility2: function () {
// need access to literal object so I can call:
}
});
I'm trying to figure out the easiest way to make the object itself available to any code, at any level, inside the object (in place of "something").
The best I've been able to do is to add a this: this property to the object and then inside of methods I can put var module = this, which works but requires that variable to be added to each module. I'd like to see if there's another way that wouldn't require adding a variable to each method. Thanks.
Thanks for the comments and, zzzzBov, thanks for your suggestions.
However, it looks like the below code will work best for my needs. The devs on my team are writing a lot of these modules and I need the solution to be clear to them. Having to call $.proxy could make it less clear. I was hoping to avoid having to put var module = this in each method, so it would be cleaner, but it seems that it's not possible without it.
framework.addModule({
id: "test-module",
init: function () {
var module = this;
$("div").click(function () {
module.utility1();
});
},
utility1: function () {
var module = this;
module.utility2();
},
utility2: function () {
}
});
If anyone has a cleaner solution, let me know.
jQuery has a proxy method which will bind the function to a specific context. This would turn your event binding into:
$('div').click($.proxy(this, 'utility1'));
Alternatively, instead of using an object literal to instantiate the module object, you could instantiate an anonymous function:
framework.addModule(new function () {
this.id = 'test-module';
this.init = function () {
$('div').click($.proxy(this, 'utility1'));
};
this.utility1 = function () {
...more code...
};
this.utility2 = this.utility1;
});

Maintaining Scope

I have a general question about maintaining the scope of this in an object. Here's a simplified snippet of code. Take note of the var that = this line and inside the event handler where I call that.showMenu().
var MyObj = {
init : function(target){
this.$Target = $(target);
this.$Menu = $(target).find('.menu');
this.eventBindings();
},
eventBindings : function(){
var that = this;
this.$Target.on('click', '.anchor', function(e){
e.preventDefault();
that.showMenu();
//some other code
});
},
showMenu : function(){
this.$Menu.show();
}
};
MyObj.init('.myTarget')
Code should be somewhat self explanatory. Typically I try to create reusable methods outside of my eventBindings(). The problem I continually run into is passing through this which would refer to MyObj into the event handler so I can call this.showMenu().
To overcome the obstacle I always assign this to a variable called that so when I'm further down the scope I have a reference. But I feel like this can't be the best method... can someone suggest a better alternative?
What you are doing is the best method. In Javascript this is scoped dynamically (binding depends on stack, that is on the place from where the function was called), all the other variables - are scoped statically (binding depends on static placement of variable in your code).
And since Javascript treats this in a special way, don't feel bad about treating it in a special way too.
You could encapsulate what you are doing now in a function - many libraries provide such a facility, it is usually called "bind". But this will not change what really happens, only hide it (and use up some resources while doing this). Such function could look a bit like:
function whatever (functionToProcess, thisToFreeze) {
return function() {
functionToProcess.apply(thisToFreeze, arguments); // apply is built in
}
}
Further to #Pointy's comment, using Function.prototype.bind:
onClick: function(e){
e.preventDefault();
this.showMenu();
//some other code
},
eventBindings : function(){
this.$Target.on('click', '.anchor', this.onClick.bind(this));
},
You could pass it in as event data:
this.$Target.on('click', '.anchor', {obj:this}, function(e){
e.preventDefault();
e.data.obj.showMenu();
//some other code
});
or store it on the element, but neither are really any different that declaring another variable outside like you are.

javascript: anonymous function expose functions (how frameworks really works)

i was exploring in the last few days how big frameworks works , how they assign their function name and it can't(?) be override , i pretty much know how framework work with anonymous function , for example they do it this way or similar version :
(function(){
var Sizzle = function (){
var x;
};
Sizzle.f = function(){
alert("!");
};
window.Sizzle = Sizzle;
})();
i still don't get few things about those huge frameworks and i hope i can find answer :
how do they assign function name and the name can't be override?
in the code above to call the function i need to write Sizzle.f() to get the function to work , but when i use jquery i don't write Jquery.show() , just show() , how do they vanish the "jquery" from "jquery.show()" function call?
by saying the name can't be override i mean , if i create function with one of the jquery functions names , the jquery function will work.
thanks in advance.
As has been shown for #2, it's really easy for BIG_NAMESPACE.Functions.doStuff to be added to anything you want.
var _ = BIG_NAMESPACE.Functions.doStuff;
_(); // runs BIG_NAMESPACE.Functions.doStuff;
As for #1:
Most libraries DO let their functions be overwritten.
It's the values that are inside of the framework's closure which are preserved, for safety reasons.
So you could do something like:
BIG_NAMESPACE.Functions.doStuff = function StealEverything() {};
(BIG_NAMESPACE.Functions.doStuff === StealEverything) // true;
But doStuff would have NO access to any of the variables hidden inside of the framework's closure.
It would also mean that until the page was reloaded, doStuff would also not work the way you want it to.
HOWEVER, in newer versions of JavaScript (ECMA5-compatible browsers), it WILL be possible to do something like what you're suggesting.
BIG_NAMESPACE = (function () {
var do_stuff = function () { console.log("doin' stuff"); },
functions = {
set doStuff (overwrite) { }
get doStuff () { return do_stuff; }
};
return { Functions : functions };
}());
Then, this will work:
BIG_NAMESPACE.Functions.doStuff(); // "doin' stuff"
BIG_NAMESPACE.Functions.doStuff = function () { console.log("ain't doin' jack"); };
BIG_NAMESPACE.Functions.doStuff(); // "doin' stuff"
However, Frameworks aren't going to use this for a LONG time.
This is not even remotely backwards compatible. Maybe in 2016...
There were defineGetter and defineSetter methods as well, but they aren't a formal part of the JavaScript language. Like innerHTML, they're things that the browser vendors put in, to make life better... ...as such, there's no real guarantee that they're going to be in any/all browsers your users have. Plus, they're deprecated, now that new browsers use the get and set constructs that other languages have.
(function(){
var jqueree = {};
jqueree.someval = 22;
jqueree.somefunc = function(){ alert(this.someval); };
window.jqueree = jqueree;
window.somefunc = function(){ jqueree.somefunc.call(jqueree); };
window.$$$ = jqueree;
})();
// all equivalent
window.somefunc();
window.jqueree.somefunc();
$$$.somefunc();
somefunc();
Answering your Questions
At the top of jQuery you'll see: var jQuery = (function() {, which creates the local function (its incomplete; the }); occurs elsewhere).
At the very end of jQuery you'll notice the following, which is how it attaches it to the global namespace:
// Expose jQuery to the global object
window.jQuery = window.$ = jQuery;
I have never seen a jQuery function called without referencing the jQuery object. I think you always need to use jQuery.show() or $.show(); however maybe you're saying you don't have to call window.jQuery.show(), which you are permitted to drop the window, since that is the default.
Using your example
(function(){
/* This is where Sizzle is defined locally, but not exposed globally */
var Sizzle = function (){
var x;
};
/* If you put "window.f = Sizzle.f = function(){" then you could *
* call f() w/o typing Sizzle.f() */
Sizzle.f = function(){
alert("!");
};
/* The following line is what makes it so you can use Sizzle elsewhere *
* on your page (it exposes it globally here) */
window.Sizzle = Sizzle;
})();
use function _name_() {} and the name is static
the simply use var $ = jQuery; to create an alias.
jQuery works this way:
Supposed you have this jQuery code:
$("#title").show();
You have three elements to that line.
$ is a javascript function
"#title" is an argument to that function
.show() is a method call
Here's how it works.
Javascript executes the function named $ and passed it an argument of "#title".
That function does it's business, finds the #title object in the DOM, creates a jQuery object, puts that DOM element into the array in the jQuery object and returns the jQuery object.
The Javascript execution engine then takes the return value from that function call (which is now a jQuery object) and looks for and executes the .show() method on that object.
The .show() method then looks at the array of DOM elements in the jQuery object and does the show operation for each DOM element.
In answer to your question, there is no .show() all by itself. It's a method on a jQuery object and, in this example, that jQuery object is returned from the $("#title") function call.

Using Jquery (or even just Javascript), how to chain commands together

There are several functions in jquery which you can do the following:
$('#element').each().get('title').othercmd()
How can I create a class ( or a series of classes ) to replicate this behavior?
Basically, I want to something like this:
test = new Something()
test.generateSection('title').addData('somedata')
What is correct for this?
Thanks
One approach is to return "this" (the object) in each function. So you could do something like this:
<script>
var Something = function() {
this.hi = function() {
alert('hi');
return this;
};
this.bye = function() {
alert('bye');
return this;
};
}
var myObj = new Something();
myObj.hi().bye();
</script>
Just return the thing that you are operating on at the end of each method. (this usually).
You can implement a chain pattern just by returning the current instance in all the methods that you want to be able to chain.
Something.prototype.generateSection = function(title){
... code ...
this.sectionAdded = ...;
return this;
}
Something.prototype.addData = function(data)
{
... continue manipulating this.sectionAdded however you need it ..
return this;
}
And do the same with the other methods of your "class". Something to keep in mind is that you must store the objects that you will need in future calls, in your case you are generating a section, so you would have to put that inside your instance (in some private variable like sectionAdded) so you will be able to continue manipulating it from other methods.
I don't know if there is a way to easily chain together commands with plain javascript, but if you wanna try this with jQuery, you'll have to write your code as a jQuery plugin.
It's actually pretty easy and there are tons of tutorials for writing your own plugins.
One of the easiest I came across is this tutorial:
building-your-first-jquery-plugin-that.html

Javascript: which function structure to use

I was reading an article about Javascript's best practices, and kinda got confused about which function structure to use...
I guess it might have an impact on the scope of the variables and functions, but which one of these structures would you use (and which is considered the best practice)?
Structure 1: use the object literals.
var obj1 = {
_myvar : 'myval',
init: function() {
this.function1();
this.function2();
},
function1: function() {
alert('function1');
},
function2: function() {
alert('function2');
}
};
obj1.init();
Structure 2: Wrap the code in an auto-executing function.
(function(){
var _myvar = 'myval',
function1 = function() {
alert('function1');
},
function2 = function() {
alert('function2');
},
init = (function() {
function1();
function2();
}) ();
}) ();
You use the self-executing anonymous function when you don't want others to interfere with your code and/or don't want to use any global variable. If you might want to use those functions/objects/whatever somewhere else, you would want to use the first one.
"Structure 1" is appropriate when you need access to the methods and variables in an object from other parts of your code. That format should always be your preference when you're writing library code that's meant to be reused elsewhere.
"Structure 2" is appropriate when you don't want to share your code with other parts of the application, and so you want to protect the variables and functions from any interference from elsewhere.
I have found Christian Heilmann's Revealing Module Pattern to be quite useful. (Scroll down to the last "green screen" code sample on his page.)
With is pattern, you can create all of your methods/functions privately in an anonymously executed function and then choose your public interface via the returned object.

Categories