I am trying to return two values in JavaScript. Is this possible?
var newCodes = function() {
var dCodes = fg.codecsCodes.rs;
var dCodes2 = fg.codecsCodes2.rs;
return dCodes, dCodes2;
};
No, but you could return an array containing your values:
function getValues() {
return [getFirstValue(), getSecondValue()]
}
Then you can access them like so:
const [first, second] = getValues()
This is called destructuring assignment and is supported by every major JS environment. It's equivalent to the following:
const values = getValues()
const first = values[0]
const second = values[1]
You can also return an object if you want to assign a name to each value:
function getValues() {
return {
first: getFirstValue(),
second: getSecondValue(),
}
}
And to access them:
const {first, second} = getValues()
Which is the same as:
const values = getValues()
const first = values.first
const second = values.second
It is highly recommended to return an object instead of an array unless the values make sense as a simple tuple, e.g. a coordinate pair [x, y]. With an array, it's easy to forget which value is which, it's harder to add more values later, and it's marginally more difficult to correctly type with TypeScript or JSDoc.
You can do this from ECMAScript 6 onwards using arrays and "destructuring assignments". Note that these are not available in older Javascript versions (meaning — neither with ECMAScript 3rd nor 5th editions).
It allows you to assign to 1+ variables simultaneously:
var [x, y] = [1, 2];
x; // 1
y; // 2
// or
[x, y] = (function(){ return [3, 4]; })();
x; // 3
y; // 4
You can also use object destructuring combined with property value shorthand to name the return values in an object and pick out the ones you want:
let {baz, foo} = (function(){ return {foo: 3, bar: 500, baz: 40} })();
baz; // 40
foo; // 3
And by the way, don't be fooled by the fact that ECMAScript allows you to return 1, 2, .... What really happens there is not what might seem. An expression in return statement — 1, 2, 3 — is nothing but a comma operator applied to numeric literals (1 , 2, and 3) sequentially, which eventually evaluates to the value of its last expression — 3. That's why return 1, 2, 3 is functionally identical to nothing more but return 3.
return 1, 2, 3;
// becomes
return 2, 3;
// becomes
return 3;
Just return an object literal
function newCodes(){
var dCodes = fg.codecsCodes.rs; // Linked ICDs
var dCodes2 = fg.codecsCodes2.rs; //Linked CPTs
return {
dCodes: dCodes,
dCodes2: dCodes2
};
}
var result = newCodes();
alert(result.dCodes);
alert(result.dCodes2);
Since ES6 you can do this
let newCodes = function() {
const dCodes = fg.codecsCodes.rs
const dCodes2 = fg.codecsCodes2.rs
return {dCodes, dCodes2}
};
let {dCodes, dCodes2} = newCodes()
Return expression {dCodes, dCodes2} is property value shorthand and is equivalent to this {dCodes: dCodes, dCodes2: dCodes2}.
This assignment on last line is called object destructing assignment. It extracts property value of an object and assigns it to variable of same name. If you'd like to assign return values to variables of different name you could do it like this let {dCodes: x, dCodes2: y} = newCodes()
Ecmascript 6 includes "destructuring assignments" (as kangax mentioned) so in all browsers (not just Firefox) you'll be able to capture an array of values without having to make a named array or object for the sole purpose of capturing them.
//so to capture from this function
function myfunction()
{
var n=0;var s=1;var w=2;var e=3;
return [n,s,w,e];
}
//instead of having to make a named array or object like this
var IexistJusttoCapture = new Array();
IexistJusttoCapture = myfunction();
north=IexistJusttoCapture[0];
south=IexistJusttoCapture[1];
west=IexistJusttoCapture[2];
east=IexistJusttoCapture[3];
//you'll be able to just do this
[north, south, west, east] = myfunction();
You can try it out in Firefox already!
Another worth to mention newly introduced (ES6) syntax is use of object creation shorthand in addition to destructing assignment.
function fun1() {
var x = 'a';
var y = 'b';
return { x, y, z: 'c' };
// literally means { x: x, y: y, z: 'c' };
}
var { z, x, y } = fun1(); // order or full presence is not really important
// literally means var r = fun1(), x = r.x, y = r.y, z = r.z;
console.log(x, y, z);
This syntax can be polyfilled with babel or other js polyfiller for older browsers but fortunately now works natively with the recent versions of Chrome and Firefox.
But as making a new object, memory allocation (and eventual gc load) are involved here, don't expect much performance from it. JavaScript is not best language for developing highly optimal things anyways but if that is needed, you can consider putting your result on surrounding object or such techniques which are usually common performance tricks between JavaScript, Java and other languages.
function a(){
var d = 2;
var c = 3;
var f = 4;
return {d: d, c: c, f: f};
}
Then use
const {d, c, f} = a();
In new version:
function a(){
var d = 2;
var c = 3;
var f = 4;
return {d, c, f}
}
A very common way to return multiple values in javascript is using an object literals, so something like:
const myFunction = () => {
const firstName = "Alireza",
familyName = "Dezfoolian",
age = 35;
return { firstName, familyName, age};
}
and get the values like this:
myFunction().firstName; //Alireza
myFunction().familyName; //Dezfoolian
myFunction().age; //age
or even a shorter way:
const {firstName, familyName, age} = myFunction();
and get them individually like:
firstName; //Alireza
familyName; //Dezfoolian
age; //35
Other than returning an array or an object as others have recommended, you can also use a collector function (similar to the one found in The Little Schemer):
function a(collector){
collector(12,13);
}
var x,y;
a(function(a,b){
x=a;
y=b;
});
I made a jsperf test to see which one of the three methods is faster. Array is fastest and collector is slowest.
http://jsperf.com/returning-multiple-values-2
In JS, we can easily return a tuple with an array or object, but do not forget! => JS is a callback oriented language, and there is a little secret here for "returning multiple values" that nobody has yet mentioned, try this:
var newCodes = function() {
var dCodes = fg.codecsCodes.rs;
var dCodes2 = fg.codecsCodes2.rs;
return dCodes, dCodes2;
};
becomes
var newCodes = function(fg, cb) {
var dCodes = fg.codecsCodes.rs;
var dCodes2 = fg.codecsCodes2.rs;
cb(null, dCodes, dCodes2);
};
:)
bam! This is simply another way of solving your problem.
You can also do:
function a(){
var d=2;
var c=3;
var f=4;
return {d:d,c:c,f:f}
}
const {d,c,f} = a()
Adding the missing important parts to make this question a complete resource, as this comes up in search results.
Object Destructuring
In object destructuring, you don't necessarily need to use the same key value as your variable name, you can assign a different variable name by defining it as below:
const newCodes = () => {
let dCodes = fg.codecsCodes.rs;
let dCodes2 = fg.codecsCodes2.rs;
return { dCodes, dCodes2 };
};
//destructuring
let { dCodes: code1, dCodes2: code2 } = newCodes();
//now it can be accessed by code1 & code2
console.log(code1, code2);
Array Destructuring
In array destructuring, you can skip the values you don't need.
const newCodes = () => {
//...
return [ dCodes, dCodes2, dCodes3 ];
};
let [ code1, code2 ] = newCodes(); //first two items
let [ code1, ,code3 ] = newCodes(); //skip middle item, get first & last
let [ ,, code3 ] = newCodes(); //skip first two items, get last
let [ code1, ...rest ] = newCodes(); //first item, and others as an array
It's worth noticing that ...rest should always be at the end as it doesn't make any sense to destruct anything after everything else is aggregated to rest.
I hope this will add some value to this question :)
You can use "Object"
function newCodes(){
var obj= new Object();
obj.dCodes = fg.codecsCodes.rs;
obj.dCodes2 = fg.codecsCodes2.rs;
return obj;
}
All's correct. return logically processes from left to right and returns the last value.
function foo(){
return 1,2,3;
}
>> foo()
>> 3
I would suggest to use the latest destructuring assignment (But make sure it's supported in your environment)
var newCodes = function () {
var dCodes = fg.codecsCodes.rs;
var dCodes2 = fg.codecsCodes2.rs;
return {firstCodes: dCodes, secondCodes: dCodes2};
};
var {firstCodes, secondCodes} = newCodes()
I know of two ways to do this:
1. Return as Array
2. Return as Object
Here's an example I found:
<script>
// Defining function
function divideNumbers(dividend, divisor){
var quotient = dividend / divisor;
var arr = [dividend, divisor, quotient];
return arr;
}
// Store returned value in a variable
var all = divideNumbers(10, 2);
// Displaying individual values
alert(all[0]); // 0utputs: 10
alert(all[1]); // 0utputs: 2
alert(all[2]); // 0utputs: 5
</script>
<script>
// Defining function
function divideNumbers(dividend, divisor){
var quotient = dividend / divisor;
var obj = {
dividend: dividend,
divisor: divisor,
quotient: quotient
};
return obj;
}
// Store returned value in a variable
var all = divideNumbers(10, 2);
// Displaying individual values
alert(all.dividend); // 0utputs: 10
alert(all.divisor); // 0utputs: 2
alert(all.quotient); // 0utputs: 5
</script>
Few Days ago i had the similar requirement of getting multiple return values from a function that i created.
From many return values , i needed it to return only specific value for a given condition and then other return value corresponding to other condition.
Here is the Example of how i did that :
Function:
function myTodayDate(){
var today = new Date();
var day = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
var month = ["January","February","March","April","May","June","July","August","September","October","November","December"];
var myTodayObj =
{
myDate : today.getDate(),
myDay : day[today.getDay()],
myMonth : month[today.getMonth()],
year : today.getFullYear()
}
return myTodayObj;
}
Getting Required return value from object returned by function :
var todayDate = myTodayDate().myDate;
var todayDay = myTodayDate().myDay;
var todayMonth = myTodayDate().myMonth;
var todayYear = myTodayDate().year;
The whole point of answering this question is to share this approach of getting Date in good format. Hope it helped you :)
I am nothing adding new here but another alternate way.
var newCodes = function() {
var dCodes = fg.codecsCodes.rs;
var dCodes2 = fg.codecsCodes2.rs;
let [...val] = [dCodes,dCodes2];
return [...val];
};
Well we can not exactly do what your trying. But something likely to below can be done.
function multiReturnValues(){
return {x:10,y:20};
}
Then when calling the method
const {x,y} = multiReturnValues();
console.log(x) ---> 10
console.log(y) ---> 20
It is possible to return a string with many values and variables using the template literals `${}`
like:
var newCodes = function() {
var dCodes = fg.codecsCodes.rs;
var dCodes2 = fg.codecsCodes2.rs;
return `${dCodes}, ${dCodes2}`;
};
It's short and simple.
Related
How to work out which variable has the most characters.
For example :
var one = "qwert";
var two = "qwertyu"
var three ="qwertyuiop";
How to work out which variable has the most character.
First thing I am doing is counting the number of characters in each string.
var onelength = one.length;
var twolength = two.length;
var threelength = three.length;
The part I am struggling on is javascript to work out which of the above lengths has the most characters.
There's really no way to do this in Javascript (nor indeed in most languages).
What you're asking for is a kind of reflection. Conceptually, a function nameOfVariable that takes a variable and gives you it's string name in return:
nameOfVariable(one): 'one'
Not possible.
The answers above are attempts to work around that. Ultimately in real code this would be structured not as a bag of variables but as an object (which is kinda like a bag of variables, except you can recover the names)
const strings = {
one: 'abcde',
two: 'abcdef',
three: 'abcd',
};
// Return key in object corresponding to longest string,
// or null if object is empty.
const longest_string = strings => {
let max = null;
for (let name in strings) {
if (max === null || strings[name].length > strings[max].length) {
max = name;
}
}
return max;
}
console.log(longest_string(strings));
try
[one,two,three].reduce((a,c) => a.length>c.length? a:c,'');
var one = "qwert";
var two = "qwertyu";
var three ="qwertyuiop";
let r= [one,two,three].reduce((a,c) => a.length>c.length? a:c,'');
let v= Object.entries({one,two,three}).reduce((a,c) => a[1].length>c[1].length ? a:c,['','']);
console.log('longest variable:', v[0], '=', r);
var words=['ape','parrot','elephant'];
console.log( longestWord( words ) );
function longestWord( words ){
var longest = '';
words.forEach(function(element){
if(longest.length < element.length)
longest = element;
});
return longest;
}
You don't need to use JQuery for this. If you save the strings in an array:
const a = ["qwert","qwertadf","qwertfasdf"]
you can use this (using ES2015 features):
let max_length = Math.max(...a.map(e=>e.length))
If you want to know the greater element, you can use this:
a.findIndex(e => e.length === ml)
Just do Math.max();
Example:
Math.max(onelength, twolength, threelength);
This will return the highest value.
I've this code with a function, wherein a I'm trying to define an array then on the next line pushing to it:
function Spot(value) {
this.x = null;
this.y = null;
this.values = [];
this.values.push(value);
}
I've tried this:
this.values = [].push(value);
and
this.values = (this.values || []).push(value);
But failed. Is there something wrong with the code.....
You are missing the array-initialisation syntax:
var x = [ 1, 2, 3 ];
in your case, this would be:
this.values = [ value ];
More info here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
The code:
var x = ([]).push("y");
looks like it should generate an array and push the value to it. It does create the array, however the array is not returned to x, the new length of the array is returned, ie 1.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push
The push() method adds one or more elements to the end of an array and returns the new length of the array. [emphasis mine]
As noted in the comments, an alternative that is closer to your original attempt would be:
var x = ([]).concat("y");
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat
The concat() method is used to merge two or more arrays. This method does not change the existing arrays, but instead returns a new array.
Just take the value in an array.
function Spot(value) {
this.x = null;
this.y = null;
this.values = [value];
}
var point = new Spot('foo')
console.log(point);
The way you are creating the array and pushing value to it is correct. But since it is created inside the function you need to access this object outside the function in some way.
Since you are not returning anything, you can call it as a constructor.
var spot = new Spot()
function Spot(value) {
this.x = null;
this.y = null;
this.values = [];
this.values.push(value);
}
var spot = new Spot();
If you do not want to call it as a constructor than you can simply return this object.
function Spot(value) {
this.x = null;
this.y = null;
this.values = [];
this.values.push(value);
return this;
}
jQuery has made my life easier but I'm still very beginner to JavaScript. So, may be, I'm asking a very stupid question here:
var t = {
rows: 3,
columns: 5,
getCellCount: function () {
return this.rows * this.columns;
}
};
var tn = t;
tn.rows = 6;
document.write(tn.rows + " , " + t.rows); // returns 6 , 6
I also tried var tn = new t(); // but seems wrong
So, How to retrieve old intrinsic value from object so that it results 6 , 3
tn and t are both pointing to the same object, that's why when you change tn.rows it also changes t.rows. There is no such thing as old intrinsic value.
You must copy the object in order to keep the old value. There are two: shallow copy and deep copy.
Copying the key-value pairs is pretty easy with Object.create.
var newObj = Object.create(oldObj);
Now if you change the values in newObj, it will not change the original one:
var a = {a:1}, b = Object.create(a);
b.a = 2;
console.log(a.a, b.a); //1,2
However, to perform a complete copy is really complicated. See more: How do I correctly clone a JavaScript object?
PS: The new keyword you mentioned is for creating an object as in classes.
function Car(n, y){ //This is called a "constructor"
var name = n, year = y; //Private variables
return {
getName: function(){ return name; }, //Getters
getYear: function(){ return year; }
};
}
var myNewCar = new Car("Toyota", 2010);
myNewCar.getName(); //"Toyota"
myNewCar.getYear(); //2010
(This is also how you create objects in Java, if you have taken those CS courses you would recognize this pattern.)
var tn = t;
simply makes both tn and t to point to the same object in memory. So, change in one object will reflect in other as well. You can clone the object, like this
function copyObject(sourceObject) {
var result = {};
for (var key in sourceObject) {
if (sourceObject.hasOwnProperty(key)) {
result[key] = sourceObject[key];
}
}
return result;
}
var tn = copyObject(t);
You are asking to clone a JSON object.
var tn={};
for (key in t) tn[key]=t[key];
There may be other "prettier" ways, but this guarantees the clone.
The = operator in javascript just changes what the object points to, so it will not create a copy of the original object. You can take a look here to see possible ways to create a clone of the object.
If you want to create a Javascript object, the conventional way is to create a function:
// Use capitalized names for Object-creating functions.
// I guessed that you wanted a matrix of some sort.
function Matrix(rows, columns) {
this.rows = rows;
this.columns = columns;
this.cellCount = function() {
return this.rows * this.columns;
}
this.dimensions = function() {
return this.rows, + ", " + this.columns;
}
this.copy = function() {
return new Matrix(this.rows, this.columns);
}
}
var t = new Matrix(6, 3);
There are more sophisticated ways to do this, using Object.create. Look at Javascript: The Good Parts.
In other languages like Python 2 and Python 3, you can define and assign values to a tuple variable, and retrieve their values like this:
tuple = ("Bob", 24)
name, age = tuple
print(name) #name evaluates to Bob
print(age) #age evaluates to 24
Is there anything similar in JavaScript? Or do I just have to do it the ugly way with an array:
tuple = ["Bob", 24]
name = tuple[0] //name Evaluates to Bob
age = tuple[1] //age Evaluates to 24
Is there a better way to simulate Python tuples in JavaScript 5?
Update: See the answer regarding ES6, which should be favored over CoffeeScript for new projects.
Javascript 1.7 added destructuring assignment which allows you to do essentially what you are after.
function getTuple(){
return ["Bob", 24];
}
var [a, b] = getTuple();
// a === "bob" , b === 24 are both true
You have to do it the ugly way. If you really want something like this, you can check out CoffeeScript, which has that and a whole lot of other features that make it look more like python (sorry for making it sound like an advertisement, but I really like it.)
You can do something similar:
var tuple = Object.freeze({ name:'Bob', age:14 })
and then refer to name and age as attributes
tuple.name
tuple.age
This "tuple" feature it is called destructuring in EcmaScript2015 and is soon to be supported by up to date browsers. For the time being, only Firefox and Chrome support it.
But hey, you can use a transpiler.
The code would look as nice as python:
let tuple = ["Bob", 24]
let [name, age] = tuple
console.log(name)
console.log(age)
A frozen array behaves identically to a python tuple:
const tuple = Object.freeze(["Bob", 24]);
let [name, age]; = tuple
console.debug(name); // "Bob"
console.debug(age); // 24
Be fancy and define a class
class Tuple extends Array {
constructor(...items) {
super(...items);
Object.freeze(this);
}
}
let tuple = new Tuple("Jim", 35);
let [name, age] = tuple;
console.debug(name); // Jim
console.debug(age); // 35
tuple = ["Bob", 24]; // no effect
console.debug(name); // Jim
console.debug(age); // 25
Works today in all the latest browsers.
Tuples aren't supported in JavaScript
If you're looking for an immutable list, Object.freeze() can be used to make an array immutable.
The Object.freeze() method freezes an object: that is, prevents new properties from being added to it; prevents existing properties from being removed; and prevents existing properties, or their enumerability, configurability, or writability, from being changed. In essence the object is made effectively immutable. The method returns the object being frozen.
Source: Mozilla Developer Network - Object.freeze()
Assign an array as usual but lock it using 'Object.freeze()
> tuple = Object.freeze(['Bob', 24]);
[ 'Bob', 24 ]
Use the values as you would a regular array (python multi-assignment is not supported)
> name = tuple[0]
'Bob'
> age = tuple[1]
24
Attempt to assign a new value
> tuple[0] = 'Steve'
'Steve'
But the value is not changed
> console.log(tuple)
[ 'Bob', 24 ]
Unfortunately you can't use that tuple assignment syntax in (ECMA|Java)Script.
EDIT: Someone linked to Mozilla/JS 1.7 - this wouldn't work cross-browser but if that is not required then there's your answer.
This is not intended to be actually used in real life, just an interesting exercise. See Why is using the JavaScript eval function a bad idea? for details.
This is the closest you can get without resorting to vendor-specific extensions:
myArray = [1,2,3];
eval(set('a,b,c = myArray'));
Helper function:
function set(code) {
var vars=code.split('=')[0].trim().split(',');
var array=code.split('=')[1].trim();
return 'var '+vars.map(function(x,i){return x+'='+array+'['+i+']'}).join(',');
}
Proof that it works in arbitrary scope:
(function(){
myArray = [4,5,6];
eval(set('x,y,z = myArray'));
console.log(y); // prints 5
})()
eval is not supported in Safari.
As an update to The Minister's answer, you can now do this with es2015:
function Tuple(...args) {
args.forEach((val, idx) =>
Object.defineProperty(this, "item"+idx, { get: () => val })
)
}
var t = new Tuple("a", 123)
console.log(t.item0) // "a"
t.item0 = "b"
console.log(t.item0) // "a"
https://jsbin.com/fubaluwimo/edit?js,console
You can have a tuple type in Javascript as well. Just define it with higher order functions (the academic term is Church encoding):
const Tuple = (...args) => {
const Tuple = f => f(...args);
return Object.freeze(Object.assign(Tuple, args));
};
const get1 = tx => tx((x, y) => x);
const get2 = tx => tx((x, y) => y);
const bimap = f => g => tx => tx((x, y) => Tuple(f(x), g(y)));
const toArray = tx => tx((...args) => args);
// aux functions
const inc = x => x + 1;
const toUpperCase = x => x.toUpperCase();
// mock data
const pair = Tuple(1, "a");
// application
console.assert(get1(pair) === 1);
console.assert(get2(pair) === "a");
const {0:x, 1:y} = pair;
console.log(x, y); // 1 a
console.log(toArray(bimap(inc) (toUpperCase) (pair))); // [2, "A"]
const map = new Map([Tuple(1, "a"), Tuple(2, "b")]);
console.log(map.get(1), map.get(2)); // a b
Please note that Tuple isn't used as a normal constructor. The solution doesn't rely on the prototype system at all, but solely on higher order functions.
What are the advantages of tuples over Arrays used like tuples? Church encoded tuples are immutable by design and thus prevent side effects caused by mutations. This helps to build more robust applications. Additionally, it is easier to reason about code that distinguishes between Arrays as a collection type (e.g. [a]) and tuples as related data of various types (e.g. (a, b)).
Here is a simple Javascript Tuple implementation:
var Tuple = (function () {
function Tuple(Item1, Item2) {
var item1 = Item1;
var item2 = Item2;
Object.defineProperty(this, "Item1", {
get: function() { return item1 }
});
Object.defineProperty(this, "Item2", {
get: function() { return item2 }
});
}
return Tuple;
})();
var tuple = new Tuple("Bob", 25); // Instantiation of a new Tuple
var name = tuple.Item1; // Assignment. name will be "Bob"
tuple.Item1 = "Kirk"; // Will not set it. It's immutable.
This is a 2-tuple, however, you could modify my example to support 3,4,5,6 etc. tuples.
I made a tuple implementation that works quite well. This solution allows for array destructuring, as well as basic type-cheking.
const Tuple = (function() {
function Tuple() {
// Tuple needs at least one element
if (arguments.length < 1) {
throw new Error('Tuple needs at least one element');
}
const args = { ...arguments };
// Define a length property (equal to the number of arguments provided)
Object.defineProperty(this, 'length', {
value: arguments.length,
writable: false
});
// Assign values to enumerable properties
for (let i in args) {
Object.defineProperty(this, i, {
enumerable: true,
get() {
return args[+i];
},
// Checking if the type of the provided value matches that of the existing value
set(value) {
if (typeof value !== typeof args[+i]) {
throw new Error('Cannot assign ' + typeof value + ' on ' + typeof args[+i]);
}
args[+i] = value;
}
});
}
// Implementing iteration with Symbol.iterator (allows for array destructuring as well for...of loops)
this[Symbol.iterator] = function() {
const tuple = this;
return {
current: 0,
last: tuple.length - 1,
next() {
if (this.current <= this.last) {
let val = { done: false, value: tuple[this.current] };
this.current++;
return val;
} else {
return { done: true };
}
}
};
};
// Sealing the object to make sure no more values can be added to tuple
Object.seal(this);
}
// check if provided object is a tuple
Tuple.isTuple = function(obj) {
return obj instanceof Tuple;
};
// Misc. for making the tuple more readable when printing to the console
Tuple.prototype.toString = function() {
const copyThis = { ...this };
const values = Object.values(copyThis);
return `(${values.join(', ')})`;
};
// conctat two instances of Tuple
Tuple.concat = function(obj1, obj2) {
if (!Tuple.isTuple(obj1) || !Tuple.isTuple(obj2)) {
throw new Error('Cannot concat Tuple with ' + typeof (obj1 || obj2));
}
const obj1Copy = { ...obj1 };
const obj2Copy = { ...obj2 };
const obj1Items = Object.values(obj1Copy);
const obj2Items = Object.values(obj2Copy);
return new Tuple(...obj1Items, ...obj2Items);
};
return Tuple;
})();
const SNAKE_COLOR = new Tuple(0, 220, 10);
const [red, green, blue] = SNAKE_COLOR;
console.log(green); // => 220
Here are some gems:
Literals:
var obj = {}; // Object literal, equivalent to var obj = new Object();
var arr = []; // Array literal, equivalent to var arr = new Array();
var regex = /something/; // Regular expression literal, equivalent to var regex = new RegExp('something');
Defaults:
arg = arg || 'default'; // if arg evaluates to false, use 'default', which is the same as:
arg = !!arg ? arg : 'default';
Of course we know anonymous functions, but being able to treat them as literals and execute them on the spot (as a closure) is great:
(function() { ... })(); // Creates an anonymous function and executes it
Question: What other great syntactic sugar is available in javascript?
Getting the current datetime as milliseconds:
Date.now()
For example, to time the execution of a section of code:
var start = Date.now();
// some code
alert((Date.now() - start) + " ms elapsed");
Object membership test:
var props = { a: 1, b: 2 };
("a" in props) // true
("b" in props) // true
("c" in props) // false
In Mozilla (and reportedly IE7) you can create an XML constant using:
var xml = <elem></elem>;
You can substitute variables as well:
var elem = "html";
var text = "Some text";
var xml = <{elem}>{text}</{elem}>;
Using anonymous functions and a closure to create a private variable (information hiding) and the associated get/set methods:
var getter, setter;
(function()
{
var _privateVar=123;
getter = function() { return _privateVar; };
setter = function(v) { _privateVar = v; };
})()
Being able to extend native JavaScript types via prototypal inheritance.
String.prototype.isNullOrEmpty = function(input) {
return input === null || input.length === 0;
}
Use === to compare value and type:
var i = 0;
var s = "0";
if (i == s) // true
if (i === s) // false
Multi-line strings:
var str = "This is \
all one \
string.";
Since you cannot indent the subsequent lines without also adding the whitespace into the string, people generally prefer to concatenate with the plus operator. But this does provide a nice here document capability.
Resize the Length of an Array
length property is a not read only.
You can use it to increase or decrease the size of an array.
var myArray = [1,2,3];
myArray.length // 3 elements.
myArray.length = 2; //Deletes the last element.
myArray.length = 20 // Adds 18 elements to the array; the elements have the empty value. A sparse array.
Repeating a string such as "-" a specific number of times by leveraging the join method on an empty array:
var s = new Array(repeat+1).join("-");
Results in "---" when repeat == 3.
Like the default operator, || is the guard operator, &&.
answer = obj && obj.property
as opposed to
if (obj) {
answer = obj.property;
}
else {
answer = null;
}
var tags = {
name: "Jack",
location: "USA"
};
"Name: {name}<br>From {location}".replace(/\{(.*?)\}/gim, function(all, match){
return tags[match];
});
callback for string replace is just useful.
Getters and setters:
function Foo(bar)
{
this._bar = bar;
}
Foo.prototype =
{
get bar()
{
return this._bar;
},
set bar(bar)
{
this._bar = bar.toUpperCase();
}
};
Gives us:
>>> var myFoo = new Foo("bar");
>>> myFoo.bar
"BAR"
>>> myFoo.bar = "Baz";
>>> myFoo.bar
"BAZ"
This isn't a javascript exclusive, but saves like three lines of code:
check ? value1 : value2
A little bit more on levik's example:
var foo = (condition) ? value1 : value2;
The Array#forEach on Javascript 1.6
myArray.forEach(function(element) { alert(element); });
Following obj || {default:true} syntax :
calling your function with this : hello(neededOne && neededTwo && needThree) if one parameter is undefined or false then it will call hello(false), sometimes usefull
In parsing situations with a fixed set of component parts:
var str = "John Doe";
You can assign the results directly into variables, using the "destructuring assignment" synatx:
var [fname, lname] = str.split(" ");
alert(lname + ", " + fname);
Which is a bit more readable than:
var a = str.split(" ");
alert(a[1] + ", " + a[0]);
Alternately:
var [str, fname, lname] = str.match(/(.*) (.*)/);
Note that this is a Javascript 1.7 feature. So that's Mozilla 2.0+ and Chrome 6+ browsers, at this time.
Immediately Invoked Arrow function:
var test = "hello, world!";
(() => test)(); //returns "hello, world!";
I forgot:
(function() { ... }).someMethod(); // Functions as objects
Create an anonymous object literal with simply: ({})
Example: need to know if objects have the valueOf method:
var hasValueOf = !!({}).valueOf
Bonus syntactic sugar: the double-not '!!' for converting pretty much anything into a Boolean very succinctly.
I love being able to eval() a json string and get back a fully populated data structure.
I Hate having to write everything at least twice (once for IE, again for Mozilla).
Assigining the frequently used keywords (or any methods) to the simple variables like ths
var $$ = document.getElementById;
$$('samText');
JavaScript's Date class providing a semi-"Fluent Interface". This makes up for not being able to extract the date portion from a Date class directly:
var today = new Date((new Date()).setHours(0, 0, 0, 0));
It's not a fully Fluent Interface because the following will only give us a numerical value which is not actually a Date object:
var today = new Date().setHours(0, 0, 0, 0);
Default fallback:
var foo = {}; // empty object literal
alert(foo.bar) // will alert "undefined"
alert(foo.bar || "bar"); // will alert the fallback ("bar")
A practical example:
// will result in a type error
if (foo.bar.length === 0)
// with a default fallback you are always sure that the length
// property will be available.
if ((foo.bar || "").length === 0)
Here's one I just discovered: null check before calling function:
a = b && b.length;
This is a shorter equivalent to:
a = b ? b.length : null;
The best part is that you can check a property chain:
a = b && b.c && b.c.length;
I love how simple it is to work with lists:
var numberName = ["zero", "one", "two", "three", "four"][number];
And hashes:
var numberValue = {"zero":0, "one":1, "two":2, "three":3, "four":4}[numberName];
In most other languages this would be quite heavy code. Value defaults are also lovely. For example error code reporting:
var errorDesc = {301: "Moved Permanently",
404: "Resource not found",
503: "Server down"
}[errorNo] || "An unknown error has occurred";
int to string cast
var i = 12;
var s = i+"";
element.innerHTML = ""; // Replaces body of HTML element with an empty string.
A shortcut to delete all child nodes of element.
Convert string to integer defaulting to 0 if imposible,
0 | "3" //result = 3
0 | "some string" -> //result = 0
0 | "0" -> 0 //result = 0
Can be useful in some cases, mostly when 0 is considered as bad result
Template literals
var a = 10;
var b = 20;
var text = `${a} + ${b} = ${a+b}`;
then the text variable will be like below!
10 + 20 = 30