How to pass a primitive variable (like a string) by reference when calling a java script method?
Which is equivalent of out or ref keyword in C#.
I have a variable like var str = "this is a string"; and passing the str into my function and automatically have to reflect the change in str when i change the argument value
function myFunction(arg){
// automatically have to reflect the change in str when i change the arg value
arg = "This is new string";
// Expected value of str is "This is new string"
}
Primitive types, that is strings/numbers/booleans are passed by value.
Objects such as functions, objects, arrays are "passed" by reference.
So, what you want won't be possible, but the following will work:
var myObj = {};
myObj.str = "this is a string";
function myFunction(obj){
// automatically have to reflect the change in str when i change the arg value
obj.str = "This is new string";
// Expected value of str is "This is new string"
}
myFunction(myObj);
console.log(myObj.str);
Related
if objects are mutable by default why in this case it dosen't work?
How to make mutation value of the key "a" in the object "s"?
var s = {
a: "my string"
};
s.a[0] = "9"; // mutation
console.log(s.a); // doesn't work
You are trying to change a primitive String, which is immutable in Javascript.
For exmaple, something like below:
var myObject = new String('my value');
var myPrimitive = 'my value';
function myFunc(x) {
x.mutation = 'my other value';
}
myFunc(myObject);
myFunc(myPrimitive);
console.log('myObject.mutation:', myObject.mutation);
console.log('myPrimitive.mutation:', myPrimitive.mutation);
Should output:
myObject.mutation: my other value
myPrimitive.mutation: undefined
But you can define a function in primitive String's prototype, like:
String.prototype.replaceAt=function(index, replacement) {
return this.substr(0, index) + replacement+ this.substr(index + replacement.length);
}
var hello="Hello World"
hello = hello.replaceAt(2, "!!")) //should display He!!o World
Or you can just assign another value to s.a, as s.a = 'Hello World'
Strings in JavaScript are immutable. This means that you cannot modify an existing string, you can only create a new string.
var test = "first string";
test = "new string"; // same variable now refers to a new string
You try to mutate a string which not possible, because strings are immutable. You need an assignment of the new value.
Below a fancy style to change a letter at a given position.
var s = { a: "my string" };
s.a = Object.assign(s.a.split(''), { 0: "9" }).join('');
console.log(s.a);
You are trying to mutate the string using element accessor, which is not possible. If you apply a 'use strict'; to your script, you'll see that it errors out:
'use strict';
var s = {
a: "my string"
};
s.a[0] = '9'; // mutation
console.log( s.a ); // doesn't work
If you want to replace the character of the string, you'll have to use another mechanism. If you want to see that Objects are mutable, simply do s.a = '9' instead and you'll see the value of a has been changed.
'use strict';
var s = {
a: "my string"
};
s.a = s.a.replace(/./,'9')
console.log(s.a);
This question already has answers here:
What is the difference between string primitives and String objects in JavaScript?
(12 answers)
Closed 9 years ago.
What is the difference between creating a string object like this
var txt = new String("Hello World");
and this
var txt = "Heloo World";
First of all let's bust some myths. String literal is not a syntactic sugar.
> var txt = new String("Hello World");
> typeof x
"string"
> var txt2 = "Hello World";
> typeof txt2
"object"
As you can see these two things are of different type. Even more: one of them is object and the second is not. This has a practical consequence, like:
> new String("Hello World") == new String("Hello World")
false
> "Hello World" == "Hello World"
true
Another difference is that primitives are passed by value while objects by reference. This might save some memory if you are passing around lots of big strings. However both objects and literals are immutable so it really isn't a big deal (why would you pass lots of big strings if you're not going to modify them?).
Also you can add attributes to objects while you can't add them to primitive types. But that's not 100% true. You can add an attribute to the prototype of a primitive. Note that both literals and objects have the same prototype:
> String.prototype.test = 11;
> var x = new String("x");
> x.test;
11
> var y = "x":
> y.test;
11
There's very little practical use for String objects as created by new String("foo"). The only advantage a String object has over a primitive string value is that as an object it can store properties:
var str = "foo";
str.prop = "bar";
alert(str.prop); // undefined
var str = new String("foo");
str.prop = "bar";
alert(str.prop); // "bar"
Hope this helps..
The String constructor function returns an object of type String. Usually, you want a literal string value, because strictly comparing an object to a literal will always return false.
One is a string primitive and the other is a String object.
The advantage of String object over string primitive is that it can store properties
var x = "foobar"
x.y = "hello"
console.log(x.hello) /* Undefinded*/
var z = new String("foobar")
z.y = "hello"
console.log(z.y) /* hello*/
typeof x = "string"
typeof z = object.
also
x==z //true
x===z // false
Nothing much but beware of this,
var s = new String('A');
var s1 = String('A');
var s2 = 'A';
console.log(s === 'A');//fasle -- since type is Object
console.log(s1 === 'A');//true
console.log(s2 === 'A');//true
var txt = "Heloo World";
here 'txt' is a primitive data type. It has no methods, it is nothing more than a pointer to a raw data memory reference, which explains the much faster random access speed.
var txt = new String("Hello World");
If you use new, you're explicitly stating that you want to create an instance of an Object. Therefore, new String is producing an Object wrapping the String primitive, which means any action on it involves an extra layer of work.
The first returns a String object, the second returns a string.
typeof txt; //object
typeof txt2; //string
While they may act similar, txt !== txt2
The primitive data types are:
String
Number
Boolean
If you using:
var txt = "Heloo World";
this is primitive type data type alert(typeof txt); will give you string type.
In JavaScript all variable can be of object type, for each primitive their is a Object type.
var txt = new String("Heloo World");
here typeof will give you object.
For difference see jsfiddle
var str="text";
alert(typeof str); //string
var str2="text";
alert(str === str2); //true
str = new String("text changed");
alert(typeof str); //object
var str2 = new String("text changed");
alert(str === str2); //false
Nothing, really. In the first example you call the constructor of class String and put as a parameter the body of the string, where as in the second example it is done automatically at the interpretation phase.
So basically the second is syntactic sugar, where as the first isn't.
There is no difference in the functionality.
I need to store an object in localStorage - and I know that in order to do so, I have to convert the object into a string. All cool.
My problem is in actually creating the object in the first place: I have two values in sessionStorage that need to be added to the object which is then passed into localStorage. However, when I try to create the object, one value is being stored as the variable name rather than its (numeric) value. Any idea whats going on here?
var siteName = sessionStorage['1'];
var siteID = (+sessionStorage['2']);
var temp = {siteID:siteName};
alert(typeof siteID);
alert(JSON.stringify(temp));
The first alert confirms that siteID is indeed a number type, but the second alert shows that the variable name (siteID) is stored rather than its numeric value.
This line:
var temp = {siteID:siteName};
...creates an object containing a property called siteId with the value taken from the siteName variable.
If you want the property name to be taken from the siteID variable instead:
var temp = {};
temp[siteID] = siteName;
Or in ES2015 (aka "ES6") you could use the new computed property name syntax:
// ES2015+ only!
var temp = {[siteId]: siteName};
In JavaScript, you can access/create properties on objects in two different but equal ways: Using dotted notation with a literal property name:
obj.foo = "bar"; // Creates a `foo` property on `obj` with the value `"bar"`
...or using bracketed notation and a string:
obj["foo"] = "bar"; // Does the same thing
The keys in object initializers like your var temp = {siteID:siteName}; are always used literally (although they can optionally be in quotes); there's no way with an object initializer to have a key taken from a variable instead. So you have to do it as a two-step process, first create the object, then set the property.
So, if you do
temp[siteID] = siteName;
...the number in siteID will be converted to a string and will become the property name, with the value of siteName being the value.
var temp = {};
var key = 1;
temp[key] = "value";
console.log(temp[1]); // "value"
console.log(temp["1"]); // "value"
(Property names are always strings in JavaScript [for now].)
Change it to this.
var temp = {};
temp[siteName] = siteID;
Or if the typeof test was meant to show the property name, you'd reverse them.
var temp = {};
temp[siteID] = siteName;
But be aware that siteID is considered a String from that point forward.
I know we can create new properties in Javascript objects during runtime but could that property be assigned a value too? For example.
var value = "New value";
var table = new Object();
var newValue = table[value];
Now, I know that value table has a new property called "value". but does that "value key contains the information as " New Value". So, does that mean now table object is like following:
table = {
value:"New Value";
}
You're confusing accessing with assigning.
// Assigns a variable named 'value' with a value of 'New Value'.
var value = "New value";
// Creates a variable named 'table' as a blank Object.
var table = new Object(); // Alternatively - table = {};
// Attempts to access "New Value" from object "table" which returns undefined.
var newValue = table[value];
If you want to assign properties to an object you do so like this:
// Assumes table is still an object.
table['key'] = 'value';
// Note that I almost _always_ opt for the variable['key'] notation over
// the variable.key notation because it allows you to use keys
// that would otherwise not be valid as identifiers.
table['Some Key'] = 'Some Value'; // This works.
table.Some Key = 'Some Value'; // This does not.
Later, when you want to retrieve that value and store it in a new variable, that's when you do this:
var newVariable = table['key'];
Hopefully that clarifies some. Please let me know if I can expand on any part of it.
no. your statement
var newValue = table[value];
is not setting anything, and since at the time when you created table you didn't assign any property, newValue will be undefined.
If you have a value variable that is assigned a value, and you want to assign that value to table under the key value, you want to do
table['value'] = value;
or alternatively
table.value = value
Erm, no, I don't think you've got it quite right.
All that does is assign undefined to newValue, because you're trying to access table's "New Value" property, which doesn't exist.
What I think you're trying to do is this:
var value = "New value";
var table = {};
table.value = value;
I've got a feeling this might not be possible, but I would like to determine the original variable name of a variable which has been passed to a function in javascript. I don't know how to explain it any better than that, so see if this example makes sense.
function getVariableName(unknownVariable){
return unknownVariable.originalName;
}
getVariableName(foo); //returns string "foo";
getVariableName(bar); //returns string "bar";
This is for a jquery plugin i'm working on, and i would like to be able to display the name of the variable which is passed to a "debug" function.
You're right, this is very much impossible in any sane way, since only the value gets passed into the function.
This is now somehow possible thanks to ES6:
function getVariableName(unknownVariableInAHash){
return Object.keys(unknownVariableInAHash)[0]
}
const foo = 42
const bar = 'baz'
console.log(getVariableName({foo})) //returns string "foo"
console.log(getVariableName({bar})) //returns string "bar"
The only (small) catch is that you have to wrap your unknown variable between {}, which is no big deal.
As you want debugging (show name of var and value of var),
I've been looking for it too, and just want to share my finding.
It is not by retrieving the name of the var from the var but the other way around : retrieve the value of the var from the name (as string) of the var.
It is possible to do it without eval, and with very simple code, at the condition you pass your var into the function with quotes around it, and you declare the variable globally :
foo = 'bar';
debug('foo');
function debug(Variable) {
var Value = this[Variable]; // in that occurrence, it is equivalent to
// this['foo'] which is the syntax to call the global variable foo
console.log(Variable + " is " + Value); // print "foo is bar"
}
Well, all the global variables are properties of global object (this or window), aren't they?
So when I wanted to find out the name of my variables, I made following function:
var getName = function(variable) {
for (var prop in window) {
if (variable === window[prop]) {
return prop;
}
}
}
var helloWorld = "Hello World!";
console.log(getName(helloWorld)); // "helloWorld"
Sometimes doesn't work, for example, if 2 strings are created without new operator and have the same value.
Global w/string method
Here is a technique that you can use to keep the name and the value of the variable.
// Set up a global variable called g
var g = {};
// All other variables should be defined as properties of this global object
g.foo = 'hello';
g.bar = 'world';
// Setup function
function doStuff(str) {
if (str in g) {
var name = str;
var value = g[str];
// Do stuff with the variable name and the variable value here
// For this example, simply print to console
console.log(name, value);
} else {
console.error('Oh snap! That variable does not exist!');
}
}
// Call the function
doStuff('foo'); // log: foo hello
doStuff('bar'); // log: bar world
doStuff('fakeVariable'); // error: Oh snap! That variable does not exist!
This is effectively creating a dictionary that maps variable names to their value. This probably won't work for your existing code without refactoring every variable. But using this style, you can achieve a solution for this type of problem.
ES6 object method
In ES6/ES2015, you are able to initialize an object with name and value which can almost achieve what you are trying to do.
function getVariableName(unknownVariable) {
return Object.keys(unknownVariable)[0];
}
var foo = 'hello';
var output = getVariableName({ foo }); // Note the curly brackets
console.log(output);
This works because you created a new object with key foo and value the same as the variable foo, in this case hello. Then our helper method gets the first key as a string.
Credit goes to this tweet.
Converting a set of unique variable into one JSON object for which I wrote this function
function makeJSON(){ //Pass the variable names as string parameters [not by reference]
ret={};
for(i=0; i<arguments.length; i++){
eval("ret."+arguments[i]+"="+arguments[i]);
}
return ret;
}
Example:
a=b=c=3;
console.log(makeJSON('a','b','c'));
Perhaps this is the reason for this query
I think you can use
getVariableName({foo});
Use a 2D reference array with .filter()
Note: I now feel that #Offermo's answer above is the best one to use. Leaving up my answer for reference, though I mostly wouldn't recommend using it.
Here is what I came up with independently, which requires explicit declaration of variable names and only works with unique values. (But will work if those two conditions are met.)
// Initialize some variables
let var1 = "stick"
let var2 = "goo"
let var3 = "hello"
let var4 = "asdf"
// Create a 2D array of variable names
const varNames = [
[var1, "var1"],
[var2, "var2"],
[var3, "var3"]
]
// Return either name of variable or `undefined` if no match
const getName = v => varNames.filter(name => name[0] === v).length
? varNames.filter(name => name[0] === v)[0][1]
: undefined
// Use `getName` with OP's original function
function getVariableName(unknownVariable){
return getName(unknownVariable)
}
This is my take for logging the name of an input and its value at the same time:
function logVariableAndName(unknownVariable) {
const variableName = Object.keys(unknownVariable)[0];
const value = unknownVariable[variableName];
console.log(variableName);
console.log(value);
}
Then you can use it like logVariableAndName({ someVariable })