Weird syntax in JavaScript example: `var { variable } = value` [duplicate] - javascript

This question already exists:
What is `var { comma, separated, list } = name;` in JavaScript? [duplicate]
Closed 7 years ago.
Does anyone know what this syntax means in JavaScript?
var { variable } = value;
I found it in some code examples and I've never seen this before. Is this JavaScript 6? I tried googling variable syntax and es6 but no examples came up with this syntax.
Here's the full example:
var { Tab } = require('app-dev-kit/tab');
var tab = Tab({ properties });
Weirdest part is if I drop parens from { Tab } then it doesn't work (it says Tab is not a function in that case):
var Tab = require('app-dev-kit/tab');
var tab = Tab({ properties });
This doesn't work: Error: Tab is not a function.

This is an ES6 feature known as destructuring assignment that works for arrays (array destructuring) and objects (object destructuring)
The destructuring assignment syntax is a JavaScript expression that
makes it possible to extract data from arrays or objects using a
syntax that mirrors the construction of array and object literals.
Say you have a function
function foo() {
return { bar: 1, baz: 2 };
}
And you want to assign the properties of that functions returned value to local variables. Traditionally, you would do something like
var f = foo();
var bar = f.bar;
var baz = f.baz;
console.log(bar); // 1
console.log(baz); // 2
With destructuring assignment, you can do this
var {bar, baz} = foo();
console.log(bar); // 1
console.log(baz); // 2

Related

Why is the "this" value different? [duplicate]

This question already has answers here:
JavaScript object functions and `this` when unbound and returned in expression/parens
(2 answers)
How does the "this" keyword work, and when should it be used?
(22 answers)
Closed 4 years ago.
Here is an example where o.foo(); is 3 but (p.foo = o.foo)(); is 2?
function foo() {
console.log( this.a );
}
var a = 2;
var o = { a: 3, foo: foo };
var p = { a: 4 };
o.foo(); // 3
(p.foo = o.foo)(); // 2”
If I do something like this then I get 4 which is what I want. How are those 2 examples are different?
p.foo = o.foo;
p.foo(); // 4
This :
(p.foo = o.foo)();
Is pretty much the same as doing this:
d = (p.foo = o.foo);
d();
Basically what it says is that the return of an assignment is the function itself in the global context. On which a is 2.
actually your code is wrong because your snippet doesnt run, you should be doing the following: console.log( this.a );
and now, lets see how this works.
function foo() {
console.log( this.a );
}
this will call this in the scope of the caller, so lets investigate our results.
so, you are setting a=2 globally, and then in the objects o.a = 3 and p.a=4
so:
calling o.foo it will return 3 because this is pointing to o
calling p.foo it will return 4 because this is pointing to p
BUT
calling (p.foo = o.foo)(); it will return 2 because it is not pointing to any object, so it will take your scope (which is the global scope) and then it will return 2.
if you go with:
p.foo = o.foo
p.foo() //4
it will return 4 successfully because it is pointing to p.
Performing that assignment operation before the function call here:
(p.foo = o.foo)();
causes the object reference to p to be lost. If you instead wrote
p.foo = o.foo;
p.foo();
you'd get 4. As it is, you get 2 because the value of this will be window in the function.
Because that parenthesized subexpression is an assignment result, there's no object lookup directly associated with the result of the expression — the value of the assignment expression is just the function reference without a contextual object. Thus the runtime doesn't have a value to use for this when it calls the function, so this is bound by default to window (or the global object in whatever context).

Can you evaluate a property name within a JS object? [duplicate]

This question already has answers here:
How to use a variable for a key in a JavaScript object literal?
(16 answers)
Closed 7 years ago.
I know that you can evaluate the value of a property inside of a JS object, like the following:
let object = {
value: 5+5
};
I am wondering if there is any possible way to evaluate the name of an attribute with JS, i.e. achieve the following:
let object;
object[5+5].value = "ten";
As something like:
let object = {
5+5: "ten"
};
Yes in ES2015, no in ES5, but first let's clear one thing up: that's JavaScript, not JSON.
In ES2015 (formerly known as ES6):
var something = "foo";
var object = {
[something]: "bar";
};
alert(object.foo); // "bar"
Inside the [ ] can be any expression you like. The value returned is coerced to a string. That means you can have hours of fun with stuff like
var counter = function() {
var counter = 1;
return function() {
return counter++;
};
};
var object = {
["property" + counter()]: "first property",
["property" + counter()]: "second property"
};
alert(object.property2); // "second property"
JSON is a serialization format inspired by JavaScript object initializer syntax. There is definitely no way to do anything like that in JSON.
Sure. Try this:
'use strict';
let object = {
[5+5]: "ten"
};
console.log(object); // Object {10: "ten"}

Javascript - primitive vs reference types [duplicate]

This question already has answers here:
Why isn't this object being passed by reference when assigning something else to it?
(4 answers)
Closed 8 years ago.
In the below code we are passing an object. So, according to javascript we are passing a reference and manipulating.
var a = new Number(10);
x(a);
alert(a);
function x(n) {
n = n + 2;
}
But 10 is alerted instead of 12. Why?
n is local to x and first it is set to the same reference as global a. The right hand side n + 2 is then evaluated to be a number (primitive).
The left hand side of the assignment, n, is never evaluated, it is just an identifier there. So our local variable is now set to the primitive value of the right hand side. The value referenced by a is never actually modified. See
var a = new Number(10);
x(a);
alert(a); // 10
function x(n) {
alert(typeof n); // object
n = n + 2;
alert(typeof n); // number
}
When you compute
n + 2
this results in a new "native number" even if n is indeed a Number object instance.
Assigning to n then just changes what the local variable n is referencing and doesn't change the Number object instance. You can see that with
n = new Number(10);
console.log(typeof n); // ---> "object"
console.log(n + 2); // ---> 12
console.log(typeof (n+2)); // ---> "number"
n = n + 2;
console.log(typeof n); // ---> "number"
In Javascript (or Python or Lisp) there's no way to pass the "address" of a variable so that the called function mutates it. The only thing you can do is passing a setter function... for example:
function foo(setter) {
setter(42);
}
funciton bar() {
var x = 12;
foo(function(newx){x = newx;});
console.log(x); // ---> 42
}
Let me try to answer it with examples:
function modify(obj) {
// modifying the object itself
// though the object was passed as reference
// it behaves as pass by value
obj = {c:3};
}
var a = {b:2}
modify(a);
console.log(a)
// Object {b: 2}
function increment(obj) {
// modifying the value of an attribute
// working on the same reference
obj.b = obj.b + 1;
}
var a = {b:2}
increment(a);
console.log(a)
// Object {b: 3}
function augument(obj) {
// augument an attribute
// working on the same reference
obj.c = 3;
}
var a = {b:2}
augument(a);
console.log(a)
// Object {b: 2, c: 3}
Please refer the JSFiddle for working demo.
The answer is rather simple: because ECMAScript is pass-by-value and not pass-by-reference, and your code proves that. (More precisely, it is call-by-sharing, which is a specific kind of pass-by-value.)
See Is JavaScript a pass-by-reference or pass-by-value language? for some additional insight.
ECMAScript uses pass-by-value, or more precisely, a special case of pass-by-value where the value being passed is always a pointer. This special case is also sometimes known as call-by-sharing, call-by-object-sharing or call-by-object.
It's the same convention that is used by Java (for objects), C# (by default for reference types), Smalltalk, Python, Ruby and more or less every object-oriented language ever created.
Note: some types (e.g.) Numbers are actually passed directly by value and not with an intermediary pointer. However, since those are immutable, there is no observable behavioral difference between pass-by-value and call-by-object-sharing in this case, so you can greatly simplify your mental model by simply treating everything as call-by-object-sharing. Just interpret these special cases as internal compiler optimizations that you don't need to worry about.
Here's a simple example you can run to determine the argument passing convention of ECMAScript (or any other language, after you translate it):
function isEcmascriptPassByValue(foo) {
foo.push('More precisely, it is call-by-object-sharing!');
foo = 'No, ECMAScript is pass-by-reference.';
return;
}
var bar = ['Yes, of course, ECMAScript *is* pass-by-value!'];
isEcmascriptPassByValue(bar);
console.log(bar);
// Yes, of course, ECMAScript *is* pass-by-value!,
// More precisely, it is call-by-object-sharing!
If you are familiar with C#, it is a very good way to understand the differences between pass-by-value and pass-by-reference for value types and reference types, because C# supports all 4 combinations: pass-by-value for value types ("traditional pass-by-value"), pass-by-value for reference types (call-by-sharing, call-by-object, call-by-object-sharing as in ECMAScript), pass-by-reference for reference types, and pass-by-reference for value types.
(Actually, even if you don't know C#, this isn't too hard to follow.)
struct MutableCell
{
public string value;
}
class Program
{
static void IsCSharpPassByValue(string[] foo, MutableCell bar, ref string baz, ref MutableCell qux)
{
foo[0] = "More precisely, for reference types it is call-by-object-sharing, which is a special case of pass-by-value.";
foo = new string[] { "C# is not pass-by-reference." };
bar.value = "For value types, it is *not* call-by-sharing.";
bar = new MutableCell { value = "And also not pass-by-reference." };
baz = "It also supports pass-by-reference if explicitly requested.";
qux = new MutableCell { value = "Pass-by-reference is supported for value types as well." };
}
static void Main(string[] args)
{
var quux = new string[] { "Yes, of course, C# *is* pass-by-value!" };
var corge = new MutableCell { value = "For value types it is pure pass-by-value." };
var grault = "This string will vanish because of pass-by-reference.";
var garply = new MutableCell { value = "This string will vanish because of pass-by-reference." };
IsCSharpPassByValue(quux, corge, ref grault, ref garply);
Console.WriteLine(quux[0]);
// More precisely, for reference types it is call-by-object-sharing, which is a special case of pass-by-value.
Console.WriteLine(corge.value);
// For value types it is pure pass-by-value.
Console.WriteLine(grault);
// It also supports pass-by-reference if explicitly requested.
Console.WriteLine(garply.value);
// Pass-by-reference is supported for value types as well.
}
}
var a = new Number(10);
x(a);
alert(a);
function x(n) {
n = n + 2; // NOT VALID as this would essentially mean 10 = 10 + 2 since you are passing the 'value' of a and not 'a' itself
}
You need to write the following in order to get it working
var a = new Number(10);
x(a);
alert(a);
function x(n) {
a = n + 2; // reassign value of 'a' equal to the value passed into the function plus 2
}
JavaScript parameter passing works similar to that of Java. Single values are passed by value, but object attributes are passed by reference via their pointer values. A value itself will not be modified in a function, but attributes of an object would be modified.
Consider the following code:
function doThis(param1, param2) {
param1++;
if(param2 && param2.value) {
param2.value++;
}
}
var initialValue = 2;
var initialObject = {value: 2};
doThis(initialValue, initialObject);
alert(initialValue); //2
alert(initialObject.value); //3
http://jsfiddle.net/bfm01b4x/

What does it mean to add a prototype to a function? [duplicate]

This question already has answers here:
How does JavaScript .prototype work?
(26 answers)
Closed 8 years ago.
Given:
var x = function () {
};
x.prototype = { abc: 25 };
Can someone explain to me what this means. Could this be done all inside a function without the .prototype?
var x = function () {
// something here ?
};
Prototypes are how the class model works in JavaScript - you've created a class x that has a property abc which defaults to 25:
var obj = new x();
alert(obj.abc); // 25
The function x is the class constructor, it is called when a new instance of that class is created and can initialize it. And that means of course that you can just set the abc property there:
var x = function()
{
this.abc = 25;
};
var obj = new x();
alert(obj.abc); // 25
This is supposedly the less efficient approach however:
You have to manipulate each object created rather than setting the property on the prototype once and forever.
The property is stored on each object and consumes memory each time, as opposed to being stored once on the prototype.
ECMAScript Harmony has a nicer syntax for defining classes and prototypes, however this one isn't implemented in any browser yet:
class x {
constructor() {
...
}
public abc = 25;
}
This is equivalent to your code defining the prototype, merely grouping related operations a little better.

How to make an object "live" in Javascript without tying it to the DOM

I asked in IRC chat yesterday whether it was possible to have an element update with any changes to an object it references, rather than just keep the value it was given upon being declared. For example
Arr1 = [1,2,3]
i1 = Arr1.length-1
last1 = Arr1[i1]
Arr1.push(4)
Checking last1 at the end of this (arbitrary) example shows it has not updated to reflect the newly added value of 4, so objects in JS aren't "live" by default.
I'm a beginner but I'd worked this out from practice already, but was told this was actually the case... I guess my question wasn't understood.
NodeList objects are "live" however, and I'm wondering if there are other types of object in JS that do so, as it would obviously save lines of code spent updating them.
One important distinction here is that i1 does not "reference" anything here. It is simply storing the numeric result of the expression Arr1.length-1 when that line executed. Likewise, last1 may or may not reference the value that was the third element of Arr1 when line 3 executed, but it maintains no reference to Arr1 itself or anything about it.
As in some other programming languages, variables that are assigned to objects are references, so you can do this:
var obj1 = { prop1: "hello", prop2: "goodbye" };
var obj2 = obj1;
obj2.prop1 = "buongiorno";
console.log(obj1.prop1); // result is "buongiorno"
But this doesn't seem to be quite what you're describing.
It sounds like what you're describing is some sort of reactive programming. JavaScript doesn't really work the way you're imagining, but you could accomplish this using closures:
var Arr1 = [1,2,3];
var i1 = function() { return Arr1.length - 1; };
var last1 = function() { return Arr1[i1()]; };
console.log(i1()); // result is 2
console.log(last1()); // result is 3
Arr1.push(4);
console.log(i1()); // result is 3
console.log(last1()); // result is 4
Note that here, the () parentheses at the end are required to call these functions and get their current value.
One even trickier thing you could do is the following:
function capture(fcn) {
return { valueOf: fcn, toString: function() { return fcn().toString(); } };
}
var Arr1 = [1,2,3]
var i1 = capture(function() { return Arr1.length - 1; });
var last1 = capture(function() { return Arr1[i1]; });
console.log(last1 * 5); // result is 15
Arr1.push(4);
console.log(last1 * 5); // result is 20
Note however that this second technique has its limitations. You have to coerce the values into the type that you would expect or call their .valueOf() method in order for them to produce an actual value. If you just used:
console.log(last1);
You would not get any sort of friendly result.
I interpret your question as why are some variables which are copies are updated when you change the original value and others are not.
This is because some types of variables are Reference Types and others are Value Types. Numbers, dates and strings are value types and are copied whenever you assign them to a variable. Objects, Arrays (which are also an Object) are reference types and are not copied, just referenced.
This example is using value types and any change to the first variable will not be copied:
var foo = 1;
var bar = foo; // this is copying the value from the foo variable to bar
foo = 2;
console.log(bar); // 1
compared to the same thing but with a reference to an object:
var foo = {prop:1};
var bar = foo; // this is creating a reference to the foo object
foo.prop = 2;
console.log(bar.prop); // 2

Categories