This question already has answers here:
Return multiple values in JavaScript?
(20 answers)
Closed 8 years ago.
Consider the following code (demo):
function test(){
var h = 'Hello';
var w = 'World';
return (h, w);
}
var test = test();
alert(test);
On execution the function test only returns the second value (i.e. 'World'). How do I make it return multiple values?
You cannot explicitly return two variables from a single function, but there are various ways you could concatenate the two variables in order to return them.
If you don't need to keep the variables separated, you could just concatenate them directly like this:
function test(){
var h = 'Hello';
var w = 'World';
var hw = h+w
return (hw);
}
var test = test();
alert(test);
This would alert "HelloWorld". (If you wanted a space in there, you should use var hw = h+" "+w instead.
If you need to keep the two variables separated, you can place them into an array like so:
function test(){
var h = "Hello";
var w = "World";
var hw=[h,w];
return hw;
}
var test = test();
alert(test);
This allows the h and w values to still be accessed individually as test[0] and test[1], respectively. However, alert(test) here will display "Hello,World" because of the way alert() handles arrays (that is, it prints a comma-separated list of each element in the array sequentially). If you wanted to produce the same output as your example code, you would need use something like join(). join() will construct a string from an array, it takes one argument which serves as a separator between the elements. To reproduce the two alerts from my first example, you would need to use alert(test.join("")) and alert(test.join(" "), respectively.
My example could be shortened slightly by skipping the creation of the hw variable and just returning an array directly. In that case, test() would look like this:
function test(){
var h="Hello";
var w="World";
return [h, w];
}
This could also be done as an object with return { h : h, w : w };, in which case you would access the individual variables as test.h and test.w, respectively.
function test(){
var h = 'Hello';
var w = 'World';
return {h:h,w:w}
}
var test = test();
alert(test.h);
alert(test.w);
one simple way to do is to return Object containing multiple key value pairs.
The comma operator evaluates each operand and then returns the value of the last one.
You'd need to either return an array:
return [h, w];
...or an object:
return { h : h, w : w };
Which you'd then use as:
var test = test();
alert(test[0]); // "hello" - in the case of the array version
...or:
var test = test();
alert(test.w); // "world" in the case of the object version
You can return an array or a new object.
Related
So my question is how i can split the a string with backtick on each instance of variable.
I tried with \${.*?} but this will not work because ${variable} will be replaced by variable values first and than the split function will be executed.
Any idea how to do it ?
let a = 2
let b = 4
let x = `Superman${a}hello${b}one more`.split(/\${.*?}/g)
console.log(x)
On side not: I don't want a solution with wrapping it to " or '.
console.log('`Superman${a}hello${b}one more`'.split(/\${.*?}/g))
After the line executes, there is no way to get the original template string. However, you can use a tag function/tagged template literal to get the parts of the string, including the substitution values:
function Test() {
console.log(arguments)
return arguments.length - 1
}
let a = 2
let b = 4
let c = Test `Superman${a}hello${b}one more`
console.log(`This template string has ${c} substituted values`)
To clarify my comment to the original question here is an example of what the default Template Literal Function does:
function defaultTemplateLiteralFn(strs, ...args) {
return strs.map((str, idx) => str+(args[idx]||'')).join('');
}
const test = "special test";
const a = 10;
const b = 432;
console.log(`This is a ${test}. "${a}+${b}=${a+b}"`)
console.log(defaultTemplateLiteralFn`This is a ${test}. "${a}+${b}=${a+b}"`)
When you use a tagged template (IE: You don't provide a function to handle the template literal) The the language provides a default function that does something similar to what I do in my function defaultTemplateLiteralFn above. It returns the combined parts of the string with the values.
The example function takes each part of the string and puts the appropriate value after the string. If there is no value then it uses a blank string.
One way i have done is using template literal. i have seen this is being used in a in a library called styled-components which allows us to write css with js.
Would love to see other methods if there are any ?
function splitOnVariable(str, age){
// first argument to function will always be array of strings provided in input string.
return str
}
let a = 1;
let b = 2;
console.log(splitOnVariable`hello${a} break me on variable${b} !!!`)
function swap(x,y){
var t=x;
x=y;
y=t;
}
This won't work. when you swap(a,b), variable a and b get copied into the function and whatever happens in that function doesn't affect the real value of a and b. I want something like this:
(function(){
a=1;
b=2;
function swap(){//something}
swap(a,b);
console.log(a) //2
console.log(b) //1
})()
How to do this?
If you are using the latest version of JavaScript (ES2015), then you can use the new language feature called "destructuring". You don't need a function. It looks like this:
let a = 1;
let b = 2;
// swap!
[b, a] = [a, b];
If you want a function, you can do it like this:
function swap(a, b) {
return [b, a]
}
[a, b] = swap(a, b);
Looking at this code, I kind of prefer the function, though it is a bit superfluous. I like how expressive it is. You aren't left puzzling over what the code does.
You can't. Arguments are passed by value, even in the case of objects. It's just that the value passed for them is a reference to the object.
Basically this means that any arguments you receive have no actual connection to the original variables you passed in except that they may share a reference.
Imagine you've written a and b on a piece of paper. In JS, the only way to share those values with a function is to copy them on to a different piece of paper and hand it to the function. So even if that function scratches out a on the new piece of paper and replaces it with b, it doesn't change what you have written on the original piece of paper.
In short, it is not possible to change the value of a variable which was used as an argument for a function.
As mentioned in the answers above, Arguments are only passed by value. If you really need to achieve the swap, you can use the 2 variables algorithm:
var a = 10, b = 20;
a = a + b;
b = a - b;
a = a - b;
console.log (a+" "+b); // 20 10
you can set a variable outside the scope of the function so you can use it inside the function, this is something you can do:
<head>
<script>var x=0, y=1;</script>
</head>
<script>
function swap()
{
var t = x;
x = y;
y = t;
}
</script>
or even this works
<script>
var x=0; y=1;
function swap(id1, id2)
{
var t = x;
x = y;
y = t;
}
console.log(x+" "+y);
</script>
I used this quite a lot and works fine. the x and y can be taken from any where and will work inside a function no problem.
you can also do
function(id1, id2)
{
x=document.getElementById(id1);
y=document.getElementById(id2);
var t = x.value;
x.value = y.value;
y.value = t;
}
function swap(value) {
value.first = value.first + value.second;
value.second = value.first - value.second;
value.first = value.first - value.second;
}
// declared an object named value which has two keys - first and second corresponding to the first and the second values respectively
var value = {
first: 1,
second: 2
}
console.log(value.first, value.second) // prints 1 2
swap(value);
console.log(value.first, value.second); // prints 2 1
Let's say I have a complex object with properties that have properties.
var x = {};
x.A.B = 'Hello';
x.A.C = 'World!';
x.D.E = 100;
x.D.F = 2.5;
Is there anything I could put in a single set of square brackets in order to get back any of these properties? A simple test shows that x['A.B'] does not return 'Hello'. Is there any syntax for doing this?
If you don't want to iterate you could do it fairly safe with eval in strict mode. Not that I recommend doing this. But it's a way to do it.
var x = {A:{}};
x.A.B = 'Hello';
var propertyPath = 'A.B';
var value = eval('"use strict"; x.' + propertyPath);
console.log(value);
Another more reusable way would be to create a new Function object instead of using eval.
function propertyValue(obj, propertyPath) {
'use strict';
return (new Function('obj', 'return obj.' + propertyPath))(obj);
}
var value = propertyValue(x, 'A.B');
It is practically the same but has a clear definition.
I am trying to reproduce some code from the book "Javascript: The Good Parts" by Douglas Crockford. The idea is to use closures for object encapsulation and avoid Javascript's inherent global variables.
var serial_maker = function ( ) {
// Produce an object that produces unique strings. A
// unique string is made up of two parts: a prefix
// and a sequence number. The object comes with
// methods for setting the prefix and sequence
// number, and a gensym method that produces unique
// strings.
var prefix = '';
var seq = 0;
return {
set_prefix: function (p) {
prefix = String(p);
},
set_seq: function (s) {
seq = s;
},
gensym: function ( ) {
var result = prefix + seq;
seq += 1;
return result;
}
};
}( );
var seqer = serial_maker( );
seqer.set_prefix = 'Q';
seqer.set_seq = 1000;
var unique = seqer.gensym( ); // unique is "Q1000"
Chrome is picking up the error:
Uncaught TypeError: Property
'serial_maker' of object [object
DOMWindow] is not a function
(anonymous function)
What am I doing wrong?
EDIT: I should say this code is entirely copy and pasted from the book...
You are trying to execute the result of a function as a function, and are assigning values to functions.
Try:
var seqer = serial_maker;
seqer.set_prefix('Q');
seqer.set_seq(1000);
var unique = seqer.gensym();
Also see this jsFiddle
There are two errors in this code example:
The definition of serial_maker is finished with () which invokes the anonymous function. That makes the next line:
var seqer = serial_maker();
erroneous since serial_maker is not the function but the object returned by the anonymous function.
Once the previous error is fixed the two lines:
seqer.set_prefix = 'Q';
seqer.set_seq = 10000;
should change to:
seqer.set_prefix('Q');
seqer.set_seq(10000);
(Source: http://oreilly.com/catalog/errata.csp?isbn=9780596517748&order=date)
I am currently working through the book and I see a redundant pair of parentheses () in your posted code, when I compare it to the book.
You have:
}
};
}( );
it should be:
}
};
};
Along with, the additional answers where the 'Q' and the 1000 need to be wrapped in ().
This question already has answers here:
how do I compare 2 functions in javascript
(6 answers)
Closed 6 years ago.
how to compare two static functions in javascript equal or not equal?
String(f1) === String(f2)
var f1 = f2 = function( a ){ return a; };
here, you can use f1 === f2 because they're pointing to the same memory and they're the same type
var f1 = function( a ){ return a; },
f2 = function( a ){ return a; };
here you can use that byte-saver Andy E used (which is implicitly converting the function to it's body's text as a String),
''+f1 == ''+f2.
this is the gist of what is happening behind the scences:
f1.toString( ) == f2.toString( )
Edit: Looking back on this post over a year after, I agree with #kangax - you should probably never do this.
Whenever I need to compare functions I make sure there is no scope ambiguity and use the same function object.
Say I have some a pair of library functions that take a callback as one of the parameters. For the sake of this example create1minuteCallback function will set a 1 minute timer and call the callback on each tick. kill1minuteCallback will turn off the callback and you must pass the same callback function as you did for create1minuteCallback.
function create1minuteCallback(callback){
//implementation
}
function kill1minuteCallback(callback){
//implementation
}
Quite clearly this will not work as the function we are passing is different on the second line:
create1minuteCallback(function(){alert("1 minute callback is called");});
kill1minuteCallback(function(){alert("1 minute callback is called");});
I normally do this:
function callbackFunc(){alert("1 minute callback is called");}
create1minuteCallback(callbackFunc);
kill1minuteCallback(callbackFunc);
Well, as simply as that - if you are going to compare functions, you do it for a reason I assume. What is your reason?
My reason was to not run a certain function twice.
I did it this way (just snippet code to get the idea)
var x = function(){
console.error("i am a functionX");
}
var y = function(){
console.error("i am a functionX");
}
var z = function(){
console.error("i am a functionZ");
}
var x2= x;
var obj = new Object();
obj[x] = "";
obj[x2] = "";
obj[y] = "";
obj[z] = "";
obj.abc = "xaxa";
for (prop in obj) {
if (obj.hasOwnProperty(prop)) {
console.error(obj[prop] + " hello " + prop);
}
}
Function x and y are the same, even though they have different whitespaces. x and y are not the same as z, since z has a different console.error.
Btw open your firebug console to see it in the jsbin example