JavaScript /jQuery variable scope causing errors - javascript

I have a really simple snippet of code and a really (probably) simple change I need to make.
I can't access a variable that I need to in my jQuery script:
var Objects; // Used to store stuff
enable_reordering();
function enable_reordering()
{
$('a.move-object').click(function(){
Objects.moveMe = $(this);
$('#image-title').text( $(Objects.moveMe).attr('data-child-title') );
return false;
});
}
When I try to change the value of Objects.moveMe to anything, my browser moans that Objects is not set. (Error: Objects is undefined).
How can I make it so that I can use variables in and out of functions throughout my entire script?
Update:
The error is caused by the line
$('#image-title').text( $(Objects.moveMe).attr('data-child-title') );
where I first try and use the variable.

try: http://jsbin.com/ocodoz/
var a;
alert(a);
a === undefined But declared in the current scope..
Your Object have to be set to an object
var Objects = {};

It's not a scope issue. The problem is that, as the error says, Objects is undefined. It looks like you want to set a property of it, so initialize it as an object literal:
var Objects = {};
Currently, what you are trying to do is effectively:
undefined.moveMe = $(this);
When you declare a variable, its value is undefined until you assign some other value to it. By assigning an empty object literal to it, you can then set properties of that object.

Related

dynamic object definition

This is a serious question, It has been nagging me for a while. In JavaScript you can declare a variable which has no type. It's type is often dynamic, depends on further value assigned to it.
e.g
var text;
typeof(text); //undefined
text = 'someText';
typeof(text); //string
So as we know that Javascript can dynamically change variable's type why these assignments are invalid then?
e.g
var someObj;
someObj.a = 'hello world';
console.log(someObj) //TypeError
var someTable;
someTable[0] = 'hello world';
console.log(someTable[0]) //TypeError
where this problem can be fixed just by adding definition to variable declaration:
var someObj = {};
var someTable = [];
I'd expect a good explanation of this problem. Thanks for answers.
There's a big difference between declaration and initialisation of variables.
When you declare a variable without initializing it with a value, its type will be undefined, so when you will try to call it or access it, it will give undefined, because simply there were no value defined for the variable.
That's why it should be initialized:
var someObj = {};
var someTable = [];
So you can treat it as a string, an object or an array according its initialized value.
Documentation:
Please take a look at variables MDN Reference for further reading, where it says:
A var statement declares variables that are scoped to the running execution context’s VariableEnvironment. Var variables are created when their containing Lexical Environment is instantiated and are initialized to undefined when created. [...] A variable defined by a VariableDeclaration with an Initializer is assigned the value of its Initializer’s AssignmentExpression when the VariableDeclaration is executed, not when the variable is created.
You're getting confused about where the error is thrown. In your first example:
var someObj;
someObj.a = 'hello world'; // the error is thrown here
That error is thrown because someObj is undefined (not undeclared). So, you can't access the property a on undefined.
The same explanation applies for your second example:
var someTable;
someTable[0] = 'hello world'; // the error is thrown here
You're trying to access index 0 of undefined.
The reason that defining them as {} and [], respectively, fixes your issue, is that you are then accessing property a of {} and index 0 of [].
1) Data types in Javascript are not dynamic, they are mutable. This means that depending on kind of operation you are applying to them they can change from being something into another thing (e.g. a number can become a string doing something like this: 4 + 'a').
2) The "error" is a consequence of having a variable not initialized. In Javascript when you are doing this:var something = 'a'
you are doing two operations, a declaration, and an assignment. If you don't do the assignment and you try to access to a property of the object you have declared it will throw an error. In your case, you are declaring a variable but not initializing it to the "compiler" can't access the "a" property or the position 1 because it is of type undefined.

want to access variable from function to render function in backbone

getGeoLevelDetails: function(id) {
window.gid = id;
}
I want to access window.gid in renderGeoLevelDetails function
renderGeoLevelDetails: function(response, obj){
var id = this.getGeoLevelDetails.gid;
console.log(id);
}
It isshowing me output as
Uncaught TypeError: Cannot read property 'gid' of undefined
There are a few errors in your approach.
First you are defining a global variable assigned to the DOM window object, this inside a function which i don't really know where it's declared. But this is not really important at this phase.
Second you want to obtain the value assigned to the global variable by calling the above function, which does not return anything.
You have a few options here: either assign the value to the global variable (which is a very bad practice, this should be avoided in any case).
The better approach would be to simply return id:
getGeoLevelDetails: function(id) {
return id;
}
Later you can obtain this id by calling in the renderGeoLevelDetails function.
renderGeoLevelDetails: function(response, obj) {
var id = this.getGeoLevelDetails();
}
Please note this is working only if you are calling the this.getGeoLevelDetails function from the same scope, because this is an instance of the same object.
There is another big error in your code regarding this line:
this.getGeoLevelDetails.gid;
First your are not invoking as a function but as an instance variable, expecting to return a globally declared object. This is the reason you are getting:
Uncaught TypeError: Cannot read property 'gid' of undefined
TL;DR
To sum up, if you wish to transfer a value from a model to a view you can access this by calling the model inside the view, or if you wish to obtain a value inside the same view you can use the approach presented above.
If none of the above solutions are fitted for your needs there is another method you can approach: to extend the Backbone object, then declare an object variable which receive the desired value. This way you will eliminate the global pollution issue:
Example:
Backbone.Details = _.extend({}, Backbone.Router);
Backbone.Details.geoLevel = id;
This variable: Backbone.Details.geoLevel then will be accessible from anywhere in your application.

why can't global variables be deleted?

How come a properly declared global variable can't be deleted?
I don't know if this is across all program languages, but I know that in JavaScript it can't be deleted.
Source: Javascript the Definitive Guide O'Reilly.
When you use global variables and you want to be able to delete them, you should easily define them in a global object, without using var in your statement, like:
let's say you want to define a global varible in your code, and you need to be able to delete them whenever you want, so if you do:
function myfunc(){
var name = "Robert";
console.log(delete name);
}
and call it in your console you would have, false as the result of delete statement, which means it has not got deleted, but if you do it like:
function myfunc(){
var obj = {};
obj.name = "Robert";
console.log(delete obj.name);
}
then your result would be true, which means it gets deleted now.
now for global object if you create it like:
window.myobj = {};
then you can delete it and it actually get deleted:
delete window.myobj;
or
delete window["myobj"];
The thing is when you create your variable using var, in the window context, although it is on object in the window, but it doesn't get deleted, for instance if you do:
var myobj = {};
in the browser dev console, it gets defined in the window, and you can have it like:
window.myobj
but you can not delete it, because you have defined it in a var statement.
But do not forget to set it to null, if you really want it to get deleted from memory:
window["myobj"] = null;
delete window["myobj"];
As was stated in this answer by user Eric Leschinski
Delete a variable in JavaScript:
Summary:
The reason you are having trouble deleting your variable in JavaScript
is because JavaScript won't let you. You can't delete anything created
by the var command unless we pull a rabbit out our bag of tricks.
The delete command is only for object's properties which were not
created with var.
JavaScript will let you delete a variable created with var under the
following conditions:
You are using a javascript interpreter or commandline.
You are using eval and you create and delete your var inside there.
or you can set null to an variable which will behave like a deleted object
When variable is created in global scope then automatically DontDelete property is added to the variable and set to the true. That is the reason global variables (or functions too) can not be deleted.
For other variables that property is false so those can be deleted.
For more clarity you can refer the article : understanding delete
With ECMAscript 5, the properties added to an object now have attributes which allow you more control over the object. These attributes are:
value - The actual value of the property
writable - If the property can/cannot be changed.
configurable - If set to false,any attempts to change its attributes will fail in strict mode (and will return false in non-strict mode)
enumerable - if the property can be iterated over when the user does for (var prop in obj) {}
These attributes can be checked with another API exposed by Ecmascript 5 called:
Object.getOwnPropertyDescriptor(obj, prop)
Now, when you create a global variable WITHOUT the 'var' keyword, like so:
sum = function (a, b) { return a + b; }
then this property 'sum' get created on the window object with configurable attribute set to true.
console.log(Object.getOwnPropertyDescriptor(window, "sum"))
... and therefore this property CAN be deleted from the window object.
delete window.sum //returns true
But when you create a property with the var keyword, then configurable property is set to false like so:
var multiply = function (a, b) { return a * b; }
console.log(Object.getOwnPropertyDescriptor(window, "multiply"))
... and now, this property CANNOT be deleted.
delete window.multiply //returns false in non-strict mode
Courtesy: John Resig

JavaScript unable to reference this object

I am trying to reference this.foo in an object I created, however this is referencing the HTML element that triggered the function. Is there any way that I can preserve the references to this in an object when it is called via an event?
Here is an example of what is going on:
$('document').on('click','button',object.action);
var object = {
foo : null,
action : function(){
this.foo = "something";
}
};
The error I would receive is
Uncaught TypeError: Object #<HTMLInputElement> has no variable 'var'
If you want to preserve this, you should probably attach your event like that:
$('document').on('click','button',function() { object.action() });
Also, if you use this object as it is presented in the question, you may as well use object instead of this:
var object = {
foo : null,
action : function(){
object.foo = "something";
}
};
Also you might want to familiarize yourself with the Bind, Call, and Apply - jQuery uses these behind the scenes to replace your this with HTML Element;
Also, var is a reserved keyword and you should not use it for a property name; if you really want to do that, use a string "var" and access it via [] notation like this:
var a = {"var": 1}
a['var']
var ist reserved word in JavaScript.
This works fine:
$(document).ready(function(){
var myObj = {
myVal: null,
action:function(){
this.myVal = "something";
}
};
myObj.action();
console.log(myObj.myVal);
});
Here link to JS Bin
I hope i could help.
Change this.var to object.var
The problem that this refers to context of where it was called from.
You call object.action from click event on button, so this is #<HTMLInputElement> here.
And, as it was already said, don't use reserved words like var as variable names
You can pass object as the this value using .apply():
$('document').on('click','button',function(){object.action.apply(object); });
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
Your this should be referencing object but it is not most likely because of the use of var which is a reserved word in JavaScript.

did prototype create a variable without using var?

Blog.prototype.signature = "TEXT"
did this statement here created a signature variable?
because this statement didnt have var keyword in it.
Also additional question
why need to use function literals or function reference to make a function inside the prototype of an object?
ex. this wont work....
obj.prototype.toString{
return "dfasdfa";
}
did this statement here created a signature variable?
No, it set a property on the prototype of the Blog class.
why need to use function literals or function reference to make a function inside the prototype of an object?
Because you need to assign something to the property obj.prototype.toString. You have to set it to equal something (in this case, function), which you're not doing with the code snippet you displayed.
Example:
obj.prototype.toString = function() {
return "dfasdfa";
}
Note that you're actually assigning a value to that property with the = function bit. Then you go on to declare the function later on.

Categories