What is use of self in jquery/ javascript? - javascript

In javascript they are using like:
var self=this;
var jquery_element= $(html_element);
self.jquery_element=jquery_elemnet
Why do we use these in javascript. I got this code from OpenStack horizon

var self=this; is useful for when you have nested functions and this can become ambiguous (in case you dont know this is a javascript keyword). self can be used to still change the this that now reffers to the this from the inner function.
var jquery_element= $(html_element); just provides a easy way to reference the jQuery element without having to constantly recreate it (also provides performance benefit for instance explained here).
self.jquery_element = jquery_element appears to be specific to that code and I'm not quite sure what it does.

It is for visibility in other scope, for using this from one scope, within other scope. Edit.
var parentFunction = function(){
this.msg = "hello world";
var parentScopeSelf = this;
var innerFunction = function(){
var innerFunctionScopeSelf = this;
console.log(this.msg);// undefined (because this now is innerFunction scope, and does not have property msg)
console.log(innerFunctionScopeSelf.msg);// undefined (because innerFunctionScopeSelf is "this" from innerFunction scope, and does not have property msg)
console.log(parentScopeSelf.msg);// hello world (because parentScopeSelf is "this" from parentFunction scope)
}
}

To answer your direct question, this is a javascript keyword, and its value will change depending on its location. By writing its value to a regular variable like self, you are preserving the value wherever self is in scope, even if this itself has changed.

Assigning this to another variable is useful when you have nested functions. For instance:
jQuery(function($) {
$('#myInput').on('keyup', function() {
var $this = $(this); // assign the jQuery's element to $this
$('div.errors').each(function() {
console.log($(this)); // outputs jQuery's object div.errors
console.log($this); // the input is still available in the nested function
});
});
});
As a recommendation, if a variable stores a jQuery element, please prepend it with $. Therefore, it should be
var $jquery_element = $(html_element);

var jquery_element= $(html_element);
is to make the html element be a jquery object that can be use with all the method of jquery.
html_element.fadeOut(); <-- will not work
$(html_element).fadeOut(); <-- will work

Related

Is it possible in Javascript to create an external closure?

Normally, to create a closure, you create it inside another function, and it gets the scope of its parent:
var parent = function(){
var a = "works!";
var subfunction(){
console.log(a); // "works!"
}
subfunction();
}
I'm trying to figure out a way to emulate this closure behavior with a function that is defined outside of the parent function. I know this is possible using parameters:
var parent = function(){
var a = "hello";
subfunction(a);
}
var subfunction(a){
console.log(a); // works, but because it's a param
}
I'm trying to figure out if there's a way to do it without having to explicitly set all parameters. I was initially thinking I'd be able to pass the functions local scope object as a parameter
var parent = function(){
var a = "hello";
subfunction(localScope);
}
var subfunction(localScope){
console.log(localScope.a); // not going to work this way
}
... but I've since discovered that it's impossible to get a reference to a function's scope. Is there some other way to emulate a closure outside of the actual scope of a function?
No, closures in JS are always lexical (i.e. referring to their parent scope).
If you want to create a closure with an explicitly set environment, you may of course use a helper function for that:
function unrelated() {
var closure = makeClosure("hello");
closure();
}
unrelated();
function makeClosure(a) {
return function() { // closes only over `a` and nothing else
console.log(a);
}
}
That's as close a you will get to an "external closure". Notice you can only pass values to makeClosure, not references to local variables. Of course you could make objects and pass the reference to them around, and with with (not recommended!) you could even make them look like variables.

Passing a window object into Javascript namespace

I'm trying to better understand namespacing in javascript and found an example of a javascript Immediately-invoked Function Expression that is taking the window object as a parameter. Here is the code from it:
var CG = CG || {};
CG.main = (function(window) {
var FOCAL_LENGTH = 8.0;
var context, width, height, startTime;
var init = function() {
var element = document.getElementById("canvas1");
context = element.getContext("2d");
width = element.width;
height = element.height;
startTime = (new Date()).getTime() / 1000.0;
tick();
}
var original_onload = window.onload || function() {};
window.onload = function() {
original_onload();
CG.main.init();
}
return {
init: init,
draw: draw_shape,
clear: clear_canvas
};
}(window));
At the end of the namespace definition, there is a line with window in parenthesis which I am confused as to the functionality of. I think that the purpose of adding the parameter of window to the end of the definition is to bind the global window variable to the namespace which will then add different properties to the window, but I can't really be sure.
In another example there is a random variable name passed into the definition of a namespace, and at the end of the namespace definition, the actual name of the namespace is passed as a parameter:
var namespace = namespace || {};
// here a namespace object is passed as a function
// parameter, where we assign public methods and
// properties to it
(function( o ){
o.foo = "foo";
o.bar = function(){
return "bar";
};
})(namespace);
console.log(namespace);
So there are really a couple of questions here:
What is the functionality of passing a parameter at the end of the namespace definition?
If my intuition for how this all works is incorrect, what is the general structure for this kind of namespace creation javascript?
Clearly I'm very new to this so any help would be appreciated, thanks.
I will try to explain this as well as I can but my understanding of it comes from Kyle Simpson. He's awesome, you should look him up. :-D
You are asking a question about immediately invoked function expressions (IIFE), passing arguments to them, and why someone would do that.
First, the reason IIFEs are being used in this context is to restrict the scope of variables.
This is important because as programs become larger and many pieces are added on you can easily have conflicts from one variable to another.
app.js could have
variable = "thing";
and shortly after somethingelse.js could have
variable = "not thing";
That is a huge problem. It is avoided in javascript by creating "modules" or functions that immediately run and run once.
That way, the variables and methods you create in your function don't "pollute the global scope/namespace."
BUT, what if you NEEDED or WANTED something to be available on the global window object?
Well, you could do that by adding it to the "window" which is the global scope in javascript.
(function Module(window){
var _thing = "private thing that only exists in this function";
window.thing = _thing;
//IS NOW AVAILABLE GLOBALLY AND EXPLICITLY ON WINDOW OBJECT
//window.onload you can wait for DOM/page before running the rest
})(window);
You also could have named it anything you wanted inside your function:
(function niftyModule(global){
global.variable = "nifty text!";
})(window)
This becomes especially important when you are using multiple libraries.
For some reason, everyone likes to use "$" as the representation of their library so you can access their private methods (which are really just functions inside an IIFE too! (its a really popular way to build good stuff).
So, what if you are using jQuery and 2 other libraries that also use $ to access their public methods/api??
Easy, you can assign which one you want to assign what variable inside your function/module scope by passing it in as an argument!
(function NiftyModule(window, $){
//Now, every time you use $ in here it means jQuery and not something else!
})(window, jQuery);
It is important to play around with functions and scope. Build some variables in different ways.
For example, is....
var text = "nifty text";
the same as
text = "nifty text";
How about if you do the same thing inside functions? How do those two versions differ?
Also, get used to building your own programs in IIFEs and properly restricting the scope of the code you are writing.
You can also return objects from functions which have the methods and variables you want to access globally on them without adding them to the window object.
It is complicated at first but in the future it saves you a lot of trouble and bugs!
Finally, In your example of:
//initialize a global variable called namespace. If this already
//existed then assign it the previous values. If not, make it an empty
//object.
var namespace = namespace || {};
//pass namespace into an IIFE. Within the IIFE refer to namespace as "o"
(function( o ){
//assign a variable to namespace
o.foo = "foo";
//assign a method to namespace
o.bar = function(){
return "bar";
};
})(namespace);
//now when you log namespace it will have those properties.
console.log(namespace);

Assigning this to inner variable say ""self [duplicate]

I saw the following in the source for WebKit HTML 5 SQL Storage Notes Demo:
function Note() {
var self = this;
var note = document.createElement('div');
note.className = 'note';
note.addEventListener('mousedown', function(e) { return self.onMouseDown(e) }, false);
note.addEventListener('click', function() { return self.onNoteClick() }, false);
this.note = note;
// ...
}
The author uses self in some places (the function body) and this in other places (the bodies of functions defined in the argument list of methods). What's going on? Now that I've noticed it once, will I start seeing it everywhere?
See this article on alistapart.com. (Ed: The article has been updated since originally linked)
self is being used to maintain a reference to the original this even as the context is changing. It's a technique often used in event handlers (especially in closures).
Edit: Note that using self is now discouraged as window.self exists and has the potential to cause errors if you are not careful.
What you call the variable doesn't particularly matter. var that = this; is fine, but there's nothing magic about the name.
Functions declared inside a context (e.g. callbacks, closures) will have access to the variables/function declared in the same scope or above.
For example, a simple event callback:
function MyConstructor(options) {
let that = this;
this.someprop = options.someprop || 'defaultprop';
document.addEventListener('click', (event) => {
alert(that.someprop);
});
}
new MyConstructor({
someprop: "Hello World"
});
I think the variable name 'self' should not be used this way anymore, since modern browsers provide a global variable self pointing to the global object of either a normal window or a WebWorker.
To avoid confusion and potential conflicts, you can write var thiz = this or var that = this instead.
Yes, you'll see it everywhere. It's often that = this;.
See how self is used inside functions called by events? Those would have their own context, so self is used to hold the this that came into Note().
The reason self is still available to the functions, even though they can only execute after the Note() function has finished executing, is that inner functions get the context of the outer function due to closure.
It should also be noted there is an alternative Proxy pattern for maintaining a reference to the original this in a callback if you dislike the var self = this idiom.
As a function can be called with a given context by using function.apply or function.call, you can write a wrapper that returns a function that calls your function with apply or call using the given context. See jQuery's proxy function for an implementation of this pattern. Here is an example of using it:
var wrappedFunc = $.proxy(this.myFunc, this);
wrappedFunc can then be called and will have your version of this as the context.
As others have explained, var self = this; allows code in a closure to refer back to the parent scope.
However, it's now 2018 and ES6 is widely supported by all major web browsers. The var self = this; idiom isn't quite as essential as it once was.
It's now possible to avoid var self = this; through the use of arrow functions.
In instances where we would have used var self = this:
function test() {
var self = this;
this.hello = "world";
document.getElementById("test_btn").addEventListener("click", function() {
console.log(self.hello); // logs "world"
});
};
We can now use an arrow function without var self = this:
function test() {
this.hello = "world";
document.getElementById("test_btn").addEventListener("click", () => {
console.log(this.hello); // logs "world"
});
};
Arrow functions do not have their own this and simply assume the enclosing scope.
It's a JavaScript quirk. When a function is a property of an object, more aptly called a method, this refers to the object. In the example of an event handler, the containing object is the element that triggered the event. When a standard function is invoked, this will refer to the global object. When you have nested functions as in your example, this does not relate to the context of the outer function at all. Inner functions do share scope with the containing function, so developers will use variations of var that = this in order to preserve the this they need in the inner function.
The variable is captured by the inline functions defined in the method. this in the function will refer to another object. This way, you can make the function hold a reference to the this in the outer scope.
Actually self is a reference to window (window.self) therefore when you say var self = 'something' you override a window reference to itself - because self exist in window object.
This is why most developers prefer var that = this over var self = this;
Anyway; var that = this; is not in line with the good practice ... presuming that your code will be revised / modified later by other developers you should use the most common programming standards in respect with developer community
Therefore you should use something like var oldThis / var oThis / etc - to be clear in your scope // ..is not that much but will save few seconds and few brain cycles
As mentioned several times above, 'self' is simply being used to keep a reference to 'this' prior to entering the funcition. Once in the function 'this' refers to something else.
function Person(firstname, lastname) {
this.firstname = firstname;
this.lastname = lastname;
this.getfullname = function () {
return `${this.firstname} ${this.lastname}`;
};
let that = this;
this.sayHi = function() {
console.log(`i am this , ${this.firstname}`);
console.log(`i am that , ${that.firstname}`);
};
}
let thisss = new Person('thatbetty', 'thatzhao');
let thatt = {firstname: 'thisbetty', lastname: 'thiszhao'};
thisss.sayHi.call(thatt);

Why assign `this` to `self` and run `self.method()`?

I'm reading the source from mongoose
Collection.prototype.onOpen = function () {
var self = this;
this.buffer = false;
self.doQueue();
};
I don't understand why the author assigns this to self and runs self.doQueue(). Why not just run:
this.buffer = false;
this.doQueue();
I'm new to javascript, thanks for help.
You're right, in this instance they could have simply used this.
The use of me or self is a bit of a hack to ensure the correct context of this is used, as within JavaScript the scope of this is variant. If for example you have an event trigger a function within your class, this would be different, and wouldn't be your object that houses the function, but instead the object that called the function. To resolve this people often use me or self to ensure they're referring to the correct object... this, as in the actual object.
Just to give more clarity to #richard said earlier,
Collection.prototype.onOpen = function () {
var self = this;
this.buffer = false;
this.onclick = function(){
//do some other operations here
//if you refer `this` here then, `this` will refer to present function not the above. so to make sure it is referring to exact object people pass this to `me` or `self`
self.doQueue();
}
};
The only reason you would usually do that is if the call to doQueue() is inside a block that will change the value of this such as another function.
In this case however it doesn't serve any purpose and was probably a remnant of older code that was not changed back.
Most likely the developer wanted consistency, but failed at doing so.
Otherwise you'd be using this in some functions, self in other functions and a mix of both in other functions, depending on where you use the object and if you use nested functions/callbacks.
By always assigning this to self and then using the latter you have one additional assignment at the very beginning of each function but you always use self to access the object.
However, what the developer did in the code you posted does not make much sense. He should either use self or this both times instead of a mix that is not even necessary.
self is a copy of 'this',but it always refer to the right object,and 'this' may not.

JavaScript Access Local Variable with Same Name in Inner and Outer Scope

Given the following JavaScript:
var someFunction = function(id) {
//do some stuff
var modifyId = function(id) {
//do some stuff
outer.id = id; //is there any way to modify the id variable in the outer scope from here?
}
}
How do you modify the id passed into the outer function scope from within the inner function scope?
Unfortunately you can't. By naming the parameter in the nested function id, you've shadowed the parameter in the outer function. Javascript contains no facility for accessing the shadowed name. The only option is to choose a different name for one of the variables.
No, there isn't. From within a function, there's no way (something weird in Mozilla's code or ES5 aside) to refer to the scope as a context in any explicit way, and there's no way to climb up the lexical scope chain in any direct way.
Good question though.
var someFunction = function(id) {
//do some stuff
var oid = id;
var modifyId = function(id) {
//do some stuff
// you can access the outer id via the oid variable
}
}
But, yes, you should just rename one of the formal parameters.
Why can't you just rename one of the variables?

Categories

Resources