Is there is any way/tool to detect the duplicated variables/methods names in the project JavaScript files?
There is no such thing as duplicate names in Javascript. You will never get an error when re-declaring a name that already exists.
To avoid overwriting existing names in Javascript, good developers do at least one of these things:
1) Carefully keep their variables out of the global scope, usually adding all names needed for the app under just one or two globally-scoped objects.
// No
var foo = 1;
var bar = 2;
var bas = 3;
// Yes
var MyApp = {
foo:1,
bar:2,
bas:3
}
2) Check that a variable name does not yet exist before creating it.
// No
var MyObj = {};
// Yes
var MyObj = MyObj || {} // Use MyObj if it exists, else default to empty object.
jsLint might help you
http://www.jslint.com/
JavaScript Lint can probably help:
http://javascriptlint.com/
http://javascriptlint.com/
Related
I have a code that is supposed to read a google sheet and push these into an array but i keep encountering an error that proData.push is not a function What could I be missing in this code?
function getData() {
var values = SpreadsheetApp.getActive().getSheetByName("Projects").getRange("A1:O").getValues();
values.shift();
var proData = [];
values.forEach(function(value) {
var proData = {};
proData.project_state = value[0];
proData.project_name= value[4];
proData.project_code= value[5];
proData.end_date= value[2];
proData.push(proData);
})
Logger.log(JSON.stringify(proData));
return proData;
}
I will appreciate help in looking at this.
This line tells the whole story:
proData.push(proData);
You're trying to push an object onto itself? Clearly this is an indication that something is wrong. So let's look at where you define proData:
var proData = {};
That at least explains the error. proData is an object, not an array. And an object indeed doesn't have a function called push. You may have thought it was an array, because you defined an identically named array here:
var proData = [];
But for the line where you call .push, how is the system to know which variable you intend for what purpose? In a higher scope you have an array named proData, but in the current scope of this operation you obscured that with an object named proData. And in doing so made the array inaccessible within the scope of the function passed to .forEach.
To avoid confusing both the JavaScript engine and yourself in this matter, simply use different variable names. Re-naming the variable in the smaller scope has a lower impact, so that's a good candidate. (Though it's not always the best choice. If the variable in the higher scope is semantically not clear about what it contains then it should be re-named.)
Something like this:
values.forEach(function(value) {
var pd = {};
pd.project_state = value[0];
pd.project_name = value[4];
pd.project_code = value[5];
pd.end_date = value[2];
proData.push(pd);
});
Say I have to following code:
var numb = $(selector).length;
And now I want to dynamicly make variables based on this:
var temp+numb = ...
How would I be able to do this?
Edit:
I know some of you will tell me to use an array. Normally I would agree but in my case the var is already an array and I rly see no other solution than creating dynamic names.
Variables in Javascript are bound to objects. Objects accept both . and [] notation. So you could do:
var num = 3;
window["foo"+num] = "foobar";
console.log(foo3);
PS - Just because you can do that doesn't mean you should, though.
In global scope (not recommended):
window["temp"+numb]='somevalue;
window.console && console.log(temp3);
In a scope you create - also works serverside where there is no window scope
var myScope={};
myScope["temp"+numb]="someValue";
window.console && console.log(myScope.temp3);
On (document).ready im would like to dynamically generate elements inside a certain parent-element. Lets call them "Candles".
Each "Candle" needs different properties for backgroundImage and color depending on their index().
After creating the page, these attributes need to be changeable via the interface. So its important to save the properties of the "candles" independent from each other.
Thats why I thought it might be useful, to generate for an object for each "Candle" to save their individual properties and to make them editable.
var candleAmount = 3;
for (var i=1; i <= candleAmount; i++) {
$("#container #candles").append("<li><img src=''></img></li>");
var Candle+i = [ "background":"+i+", "color":" - random - (ignore)" ]
};
(please dont mind any failures in the code besides the "Candle+i", I'll figure it out.)
EDIT: Ok, thank you so far. I might not made myself clear enaugh.
Here is an way more reduced example:
$("ul#candles li").each( function(i) {
candle+i = i+" Anything";
});
alert(candle4);
I would love to create an amount of variables depending on the Amount of child-objects.
What would be the correct syntax, or isn't there any?
Thank you
just put them in an array and access them via index. Result is most likely the same for you and is much better than let them floating in your scope
So is there any way, to generate object-names with an index?
Yes, in JavaScript, global variables are defined as properties of the global-object. (Inside a function, variables are defined as properties of the Activation object.) You can reference the global object by window (for browser applications) or just by this.
And because all objects are associative you can give there properties just the name you want. So, setting a global variable is equal to set a property into the global object.
var foo = "bar"; === this["foo"] = "bar";
Now, its just a small step to add a dynamic part to the name:
for(var i=0;i<10;i++) {
this['candle' + i] = i;
}
alert(candle7);
For your specific code:
$("ul#candles li").each( function(i) {
window["candle" + i] = i+" Anything";
});
alert(candle4);
I had the following question in a test today. But i had not see something like functionName.VariableName before. Not sure how that works.
Would be great if you can tell me the solution:
function Item(itemName)
{
var next_item_id = 1;
Item.item_name = itemName;
Item.item_id = next_item_id++;
}
var Item1 = Item('Desktop');
var Item2 = Item('Laptop');
var Item3 = Item('Monitor');
Anything wrong with the code above? if yes fix it. (The problem i would see is next_item_id is always 1, need to make it global?)
Modify the function so that the variable “next_item_id”, cannot be modified during run time.
My own question, how does the variable like Item.item_name work? I want to google it, but not sure what I should search for.
Thanks.
Your thinking is close in that next_item_id will always be 1, but it's generally not recommended to pollute the global namespace. Instead, wrap it in an anonymous function:
(function() {
var next_item_id = 1;
function Item(itemName)
{
//Use "this" to apply the property to the instance only
this.item_name = itemName;
this.item_id = next_item_id++;
}
var Item1 = new Item('Desktop');
var Item2 = new Item('Laptop');
var Item3 = new Item('Monitor');
})()
Also, as in Java, the general best practice in Javascript is to use camelCase rather than under_scores. Constructors are generally in UpperCamelCase. Examples:
Array //UpperCamelCase
Object.prototype.toString //toString is camelCase
This question is ambiguous, and, depending on the interpretation, there can be a number of possible answers. next_item_id is a "var" declared inside a function and naturally has an internal [[DontDelete]] and [[DontEnum]] flag. If it's a "var" and we're not using "this" as shown in my modified code, the variable is inherently not accessible outside of the function or its nested functions and therefore cannot be modified. You can use the non-standard const or you can create an object and use Object.defineProperty to create a setter that returns false assuming an ES5-compatible environment, etc.
Functions are objects in Javascript. All objects can have "properties."
Javascript functions are also objects and can have properties.
They behave like static fields in Java.
You're going about it all wrong. I'm assuming that you want to set internal variables.
If you want to create a 'constructor', do something like this:
function Item(itemName)
{
var next_item_id = 1;
this.item_name = itemName;
this.item_id = next_item_id++;
}
var Item1 = new Item('Desktop');
var Item2 = new Item('Laptop');
var Item3 = new Item('Monitor');
Both item_name and item_id will be publicly available. To make use next_item_id like you want, try this:
Item.next_item_id = 1;
Then in your constructor, do Item.next_item_id++;
Your final code should look something like this:
function Item(itemName)
{
this.item_name = itemName;
this.item_id = Item.next_item_id++;
}
Item.next_item_id = 1;
var Item1 = new Item('Desktop');
var Item2 = new Item('Laptop');
var Item3 = new Item('Monitor');
What this is doing is attaching a property to the object Item. You might be thinking, "Item is a function! How is this possible?!". Nearly everything in JavaScript is an object with mutable properties. The only things that aren't are the keywords null and undefined (AFAIK).
Item is still a function, but it also has a property next_item_id.
Also, using new will create a new instance. This is a similar concept as in Java and other programming languages. Just calling Item is like calling a function, and you'll get back whatever is returned from it (through an explicit return statement, otherwise undefined).
Answer for question 2 : Modify the function so that the variable “next_item_id”, cannot be modified during run time.
If I have interpreted your question correctly, you want to have Item.item_id as a constant that cannot be modified any where outside the constructor. I don't think we can have constants in JS.
Item1.item_id = someValue
Above line, used some where can change the item_id value of Item1.
Is there a way for javascript to detect all assigned variables? For example, if one js file creates a bunch of vars (globally scoped), can a subsequent file get all the vars without knowing what they're named and which might exist?
Thanks in advance :)
EDIT, Question Part 2:
How do I get the values of these variables? Here is what I have attempted:
This is what I ended up with, as per comment suggestions:
for (var name in this) {
variables[name] = name;
variables[name]=this[name]
}
Flanagan's "JavaScript - The Definitive Guide" gives the following on page 653:
var variables = ""
for (var name in this)
variables += name + "\n";
For Firefox, you can see the DOM tab -- easy, though not an answer to your question.
The for in loop provided in Kinopiko's answer will work, but not in IE. More is explained in the article linked below.
For IE, use the RuntimeObject.
if(this.RuntimeObject){
void function() {
var ro = RuntimeObject(),
results = [],
prop;
for(prop in ro) {
results.push(prop);
}
alert("leaked:\n" + results.join("\n"));
}();
}
See also:
Detecting Global Pollution with the JScript RuntimeObject (DHTML Kitchen article)
RuntimeObject (MSDN docs)
There is the this variable. This is an object or an array, and you can simply put:
for(i in this) { //do something }
Unfortunately, it will return everything under the this object.
This will output all the variables into the console without needing to read the variable yourself.
var variables = ""
for (var name in this)
variables += name + "\n";
console.log(variables)
/*
This could work too... but it's such a big unecessary code for something you could do in one line
var split = variables.split("\n");
for (var i in split)
console.log(split[i])
*/
If you want to assign values from one object to another, there are a couple of ways to do this:
//Way 1st
const variables= { ...this };
// or (I don't know what's the difference ;) )
// Don't forget const variables= {};
Object.assign(variables, this);
// Yes. It's very easy. You just "copy" entries from this to variables. I want to note that you are not copying a link to this, namely ENTRY.
Or
// Way 2nd. If u need to do smth. with entries.
const variables= [];
for (const name of Object.keys(this)) {
/*
Doing smth........
*/
variables[name] = this[name];
}
I want to note that this is not a way to collect all declared variables into an object (I am looking for this method myself). They are simply ways of copying the contents of one object into another.