var person = {name: "Johen", address: "USA"}
Is there a difference between the following 2 ways to access the person's attributes? Are there any performance implications?
var name = person.name
var address = person["address"]
Thanks!
They are equal. You need the array syntax if the key contains characters not allowed outside a string though. The same applies if you want to use a dynamic key - long time ago people used to use messy hacks like foo = eval('obj.' + propname); but foo = obj[propname]; is much nicer of course
IMO the obj.property syntax is much nicer since it's shorter and more natural.
Both "dot" and "square bracket" access methods for object properties are described in ECMA-262 section 11.2.1. Dot access can be used only in limited cases where the name conforms to the rules for allowed characters for identifiers.
Square bracket notation can be used where the name is evaluated from an expression. It essentially says "evaluate the expression and use the result as the property name" so you can do things like:
function foo() {return 'foo'}
var obj = {};
obj[foo()] = 'foo';
Array properties are accessed in exactly the same way as object properties - arrays are just objects with a special length property.
Related
I saw following code in a project. can anyone explain what is going on here? What will be value of Attributes? What is happening this[Attributes] = attrs line?
const Attributes = Symbol('User#attrs');
class User {
constructor (attrs) {
this[Attributes] = attrs;
}
}
Symbol creates an un-collidable key for any object:
const first = Symbol('debug-name');
const second = Symbol('debug-name');
first !== second // true;
const anObj = {};
anObj[first] = 123;
anObj[second] = 456;
console.log(anObj) // {Symbol('debug-name'): 123, Symbol('debug-name'): 456}
Note that even though the first and second variables have the same debugging string they create different keys in anObj. Anyone who has access to first can add that key to any object and it will not collide with any other key in that object.
This can be used instead of magic strings to manage protocols:
// ES5
someObject.MY_LIB_attributes = [1, 2, 3];
// Only safe if no other library uses the key
// "MY_LIB_attributes"
// ES2015+
export const Attributes = Symbol('myLib#attributes');
import { Attributes } from 'my-lib';
someObj[Attributes] = [1, 2, 3];
// Safe as long as no other library uses
// *this* Symbol instance for some other purpose.
Edit
Since you've now clarified the question to be only about the line of code this[Attributes] = attrs, see the second part of my answer for discussion of that.
Original Answer
This is a couple of the new ES6 Javascript features.
const Attributes = Symbol('User#attrs'); creates a new Symbol object. The Symbol function and object is described here. It creates a unique identifier object that can then be used for many other uses, one of which is as a property name. There are many other references on the new Symbol feature so I won't repeat all of that here.
The class definition is the ES6 method for declaring prototyped classes. Again, there are many other references on this new syntax so there is no point in repeating all that here. There's an example below of what the equivalent ES5 code is.
This line this[Attributes] = attrs; uses the Symbol generated above to set a property on the newly created object.
The class definition is equivalent to the regular constructor
declaration like this:
function User(attrs) {
this[Attributes] = attrs;
}
Discussion of this[Attributes] = attrs
Attributes is a symbol which can be used as a property name on an object. It's a way of generating a unique key that can be used as a property name. So, this[Attributes] = attrs is setting a property on the newly constructed object and it is using the Attributes symbol as the property name. This Attributes symbol is a unique value that will not match any known string (in fact it won't even match other Symbol objects) so it's a way of making a unique property name.
It is unclear why the code does this:
this[Attributes] = attrs;
instead of just something like this:
this.attrs = attrs;
We would have to see a bit more context for how that is being used and why a plain string property could not also be used in place of the Symbol as you haven't provided enough context for us to know.
One possible use is for privacy. If Attributes is not public, then this is a way of creating a property on the object that the outside world doesn't know how to access because you have to have the current value of Attributes in order to access that properly. As you've shown the code with User and Attributes in the same scope that does not seem like it is private, but perhaps only User is exported to a public scope.
Another possible use is for uniqueness. If the User object may have lots of other properties added to it by other code, then Attributes creates a unique property name that cannot collide with other property names. This seems less likely in this case, but it is one possible use of Symbols.
document.getElementById('coolid').innerHTML = "pretty cool";
The code above will, to my knowledge, access an html element object by id named 'coodid" and that object, being an element object, has a property of "innerHTML" which allows me to replace that HTML nodes text with the text "pretty cool".
I also know getElementsByName() and getElementsByClass(), etc...these all allow me to access DOM elements (which to my knowledge are objects). Ok, that's great. But is there some way to access objects I create as well? Like this:
var person = {
name : "John",
}
object.reallyCoolImaginaryGetMyObjectFunction('person').name = "Tom";
I know this might seem quite strange and perhaps even pointless, but just out of curiosity I've been wondering about this. Does anyone have any idea? Thanks.
You can if they're stored on an object, and there's one special case (globals) which are automatically stored on window.
You do it using bracketed notation and a string, e.g.:
var obj = {
foo: "bar"
};
console.log(obj["foo"]); // "bar"
Or of course if it's a global variable:
console.log(window["foo"]); // "bar"
...since global variables are properties of the global object, and we can refer to the global object on browsers as window.
Details: JavaScript has two ways to access properties: Dot notation with literal names (obj.foo), and bracketed notation with strings (obj["foo"]). In the latter case, the string can be the result of any expression, e.g.:
// These all do the same thing, in the end
console.log(obj["foo"]);
console.log(obj["f" + "o" + "o"]);
var x = "foo";
console.log(obj[x]); // x contains the string
In java script (or jquery) , what is difference between
var a = xyz[]
var a = xyz{}
I searched on internet but couldn't find any answer? please let me know if there is any difference.
That's invalid syntax.
var a = [];
Initializes an array instance.
var a = {};
Initializes an object instance.
The syntax you describe is invalid. However, if you have an array a, you can access elements of it thusly:
a[0]
And if you have an object a, you can access properties of it the same way:
a['propName']
You can also access properties with the dot notation:
a.propName
But if your property contains invalid identifier characters (anything other than a-z, A-Z, $, and _), you must use the bracket notation:
a['prop name with ## stuff']
Note that arrays can have properties and objects can have numeric property names. This is because arrays are objects in JavaScript, albeit special ones that handle numeric properties differently than objects, and have some functionality built in (as well as a length) property.
This question already has answers here:
"Variable" variables in JavaScript
(9 answers)
Closed 8 years ago.
I have two variables, one holds extra info about an object, and is named extra_info + the id of the object. The other holds the name to that variable:
selector = 'extra_info' + subscid;
I am trying to access the data stored in the variable that holds the extra info, but I can't seem to access it. Stupid, I know :-)
EDIT: So, the name of the variable that I in the end need to access is:
extra_infoXXXXX
where XXXXX is stored in subscid.
No quotes:
selector = extra_info + subscid;
Or, and I'm loathe to suggest this because it's a red flag of bad design, you can use eval():
selector = eval('extra_info' + subscid);
(Obilgatory "eval is evil" link)
EDIT
It sounds like you should stored your extra_info in an array object, with the subscid for its indexes properties!
To access, do something like extra_info[subscid].
Edit:
From your comment:
extra_infoXXXXX holds a string
...it sounds like if subscid contains "foo", you want to get the value of extra_infofoo. If so, you'll need an object to look that up; otherwise, you'll be forced to use eval.
If these extra_infoxxxx variables are globals, you can look them up on window:
selector = window['extra_info' + subscid];
If not, I hate to say, you're stuck with eval:
selector = eval('extra_info' + subscid); // Blech
But note that if you're doing that, it's best to step back and reevaluate (no pun!) your design. For instance, perhaps you could make an object with the extra info as properties:
var extra_info = {
foo: "bar"
};
Then you could look up the information like this:
selector = extra_info[subscid];
Original Answer:
It's very hard to tell from the information you've given, but I think you're looking for:
selector = extra_info[subscid];
...assuming that subscid contains the name of the property on extra_info that you want to access.
In JavaScript, you can access a property on an object using dotted notation and a literal property name:
x = foo.bar;
...or using bracketed notation and a string property name:
x = foo["bar"];
In the second case, the string can be the result of any expression. So for instance:
b = "bar";
x = foo[b];
or even
x = foo['b' + 'a' + 'r'];
To get the variabale do like this,
selector = extra_info+""+subscid['XXX']
In Javascript, you can create an object with a property name this way:
var person = { name: "Tucker" };
But also that way:
var person = { "name": "Tucker" };
Are these two equivalent? Which one is preferred?
Same goes with accessing a property:
person["name"] = "Dale";
vs.
person[name] = "Dale";
In Eloquent JavaScript, the author says that The part between the brackets can be any expression. It is converted to a string to determine the property name it refers to..
So, I guess directly putting a string between the brackets would be considered best practice.
Last but not least, properties can be accesses by using the dot notation:
person.name = "Dale";
if the property is a valid variable name. Does it actually makes sense to use this notation over the seemingly more flexible bracket notation?
These are the same, the only difference is that if your key is reserved keyword, you need the quotes:
var person = { name: "Tucker" };
var person = { "name": "Tucker" };
var person = { "for": "Tucker" }; //Need quotes here
When accessing, the same rules apply
person["name"] = "Dale"; //Sets the person object's name attribute to "Dale", the brackets are needed for variables or expressions.
person.name = "Dale"; //Same operation, different syntax
person[name] = "Dale"; //Sets the attribute equivalent to the value of the variable name, not necessarily "name"
Does it actually makes sense to use this notation over the seemingly more flexible bracket notation?
It is entirely up to you, or whoever decides your project's coding standards. The dot notation is simpler and reminiscent of Java/C/C++ (if you're into that sort of thing) and brackets, as you noted, are more flexible.
There's no 'best way', and it really depends on what you're doing.
var person = { name: "Tucker" };
Is fine, but if 'name' is actually 'name with a space' then you need:
var person = { "name with a space": "Tucker" };
For accessing properties, unless you're in a for ... in loop I would recommend dot notation:
person.name
Of course you can't do:
person."name with a space"
So do:
person["name with a space"]