I have two part question about creating namespaces in JavaScript, which one of the following is proper/better way to define a namespace:
// style 1
var company = company || {};
company.models = company.models || {};
company.models.class = {...}
// style 2
company = typeof (company) == 'undefined' ? {} : company;
company.models = company.models || {};
company.models.class = {...}
Please note there are TWO differences in the styles. First is use of typeof and Second is the style 2 does NOT use the var key.
Both these styles seem to work and now here is where it gets really confusing. If I remove the var key from style 1 then namespace does NOT work at all. I get something like company is not defined. I think it has something to do with the var creating a global variable and without var we are creating a global property as explained in here
What is the purpose of the var keyword and when to use it (or omit it)?
Would some please explain to me why the style 1 fails without the var key?
Many thanks in advance.
It's matter of likes but I prefer the first one since It is shorter and more readable.
First style 'means':
Create local variable 'company'. If it exists(and its value is not falsy) in an upper scope asign that to this variable else asign a new object.
Second one 'means'
Assign to company variable a new object if it is undefined or itself if it is defined.
The first one triggers a ReferenceError if you remove 'var' because the second reference (company = company) doesn't exists and the interpreter doesn't know how to deal with that. If it exists it will work even if you remove 'var'.
Another note for the first style is that company will be overwritten with a new object even if it is a falsy value like 0, null or ""
Related
I have a var containing a JSON string. (Here I won't parse it because it is not the main problem)
var variable = '{"name":"Johnny Appleseed"}';
var string = "variable";
I evaluate the string.
var evaluatedstring = eval(string);
Now I would like to delete the value of the var variable.
variable = undefined;
If I do:
console.log(evaluatedstring)
It works fine and returns me the JSON string as:
{"name":"Johnny Appleseed"}
But if I do:
evaluatedstring = undefined;
Of course it doesn't work.
eval(string) = undefined;
doesn't work either. (Returns the error Uncaught ReferenceError: Invalid left-hand side in assignment)
How can I delete the content that via the evaluated var?
No jQuery, please.
On Chrome 50+ so not a problem with the browser.
If you're working in the browser: Global variables in JavaScript are created as properties of the window object. Therefore, what you're trying to do can be done like this:
var variable = 'some variable';
var variableName = 'variable';
window[variableName] = undefined;
variable === undefined // Will now be true
However, just the fact that this is possible doesn't mean it's a good idea - in fact, it's just the opposite, it's bad style and will probably confuse anyone looking at your program to no end. If this is really necessary for your algorithm to work, you might want to rethink your data architecture. If this is just a scoping issue (you don't want that variable to pollute your global namespace), an IIFE will likely solve your problem.
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.
I am puzzled with this one. I have the following code.
var s = "test";
s.len = 4;
var t = s.len;
The question is why the variable t has a value of undefined.
If you check the s.len after that code it is undefined.
If you check s the value is test. Not sure what is going on here. I am sure there is an explanation, but can't get my head around that and don't know how to search that.
For those who consider to vote down. This is a question we got in a course, and we are expected to prepare for the next session with this riddle.
I am not new to programming, but I fail to research how JavaScripts treats this code. It is valid code really, execute it in your Dev Tools and you will see.
I define a property for the string s called len assign to it the value 4. This property is, I believe created, but undefined. I would like to now why is it ? Is it specific to strings in JavaScript ?
but I fail to research how JavaScripts treats this code.
That is easy: strings are primitive types in JS, which means they don't have properties by themselves.
For . operator to work with them (e.g. for .length call) javascript defines such a thing called "wrapper objects".
So when you try to access a property of a primitive object - a temporary wrapper object is created that does behave as an object, hence you can access and assign properties to it.
The problem is that the wrapper object is temporary, so after it's used to access a property the object is discarded with all its state.
That's why when you assign a .len property you cannot access it on the next line: it's lost.
So a pseudo code for what actually happens behind the scenes for your code is
var s = "test";
(new String(s)).len = 4; // here you add an attribute for a new object
// and `s` is left untouched
var t = s.len;
The question is why the variable t has a value of undefined.
Because you have defined s as a string not as an object. so s.len should be undefined!
I am not sure what are you trying to do. But if you want to get the length of s then t = s.length will simply work.
I define a property for the string s called len assign to it the value 4. This property is, I believe created, but undefined. I would like to now why is it ? Is it specific to strings in JavaScript ?
You can find the answer from this question
run :
var s1 = "test";
console.log(typeof s1)//string
var s2 = {}
console.log(typeof s2)//object
s1.len = 4;
s2.len = 4;
console.log(s1.len);//undefine
console.log(s2.len);//4
What is the name of the technique the example uses below to pass a variable to an object in javascript? And furthermore, why is it not working ("large" is not outputted to the console log as expected)?
var thumbnailBlock = new ThumbnailBlock();
thumbnailBlock.thumbnailSize = "large";
function ThumbnailBlock() {
this.thumbnailSize;
console.log("DEBUG");
console.log(this.thumbnailSize);
}
The explanation what is going wrong in your code from Willem Mulder's answer:
There is no specific name. You simply set an object property.
The 'large' is not outputted because you first create an object using the ThumbnailBlock constructur function (where it logs the this.thumbnailSize) and only then set the .thumbnailSize to "large".
You could pass the size as function argument.
function ThumbnailBlock(size) {
this.thumbnailSize = size;
}
var thumbnailBlock = new ThumbnailBlock("large");
console.log(thumbnailBlock.thumbnailSize);
Also, have a look at the The Constructor Pattern and other nice patterns on that page. I also recommend the chapter on OOP in the free book Eloquent JavaScript.
There is no specific name. You simply set an object property.
The 'large' is not outputted because you first create an object using the ThumbnailBlock constructur function (where it logs the this.thumbnailSize) and only then set the .thumbnailSize to "large".
The proper answers are already given, I just want to point out for the record that adding dynamic property won't work if your object is sealed or frozen.
function ThumbnailBlock(size) {
Object.seal(this);
}
var thumbnailBlock = new ThumbnailBlock("large");
thumbnailBlock.thumbnailSize = 10;
console.log(thumbnailBlock.thumbnailSize); // undefined
In strict mode you will raise an exception instead.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why is there a null value in JavaScript?
I don't understand what null is for. 'Undefined' as well.
It helps to appreciate the difference between a value and a variable.
A variable is a storage location that contains a value.
null means that the storage location does not contain anything (but null itself is just a special kind of value). Read that last sentence carefully. There is a difference between what null is and what null means. 99% of the time you only care about what null means.
Undefined means that the variable (as opposed to the value) does not exist.
null is an object you can use when creating variables when you don't have a value yet:
var myVal = null;
When you do this, you can also use it to check to see if it's defined:
// null is a falsy value
if(!myVal) {
myVal = 'some value';
}
I wouldn't use it this way, normally. It's simple enough to use 'undefined', instead:
var myVal; // this is undefined
And it still works as a falsy value.
Creating Objects
When you create an object in javascript, I like to declare all my object properties at the top of my object function:
function myObject() {
// declare public object properties
this.myProp = null;
this.myProp2 = null;
this.init = function() {
// ... instantiate all object properties
};
this.init();
}
I do this because it's easier to see what the object properties are right off the bat.
If a variable is not known or not initialized in the current scope it is undefined.
If you want to use a variable and indicate that it has an invalid value for instance you may want to assign it null because accessing an undefined variable will throw an error if you try to work with it (despite checking if it is undefined).
If something is undefined you also have the possibility to add it to an object. If a variable is defined but contains null you know that this variable may be used already by another part of your program.
For example, it can prepare a global variable to be used in more parts of the code.
If you start your code with var iNeedThisEverywhere = null; then you can use it inside more objects/actions in the code, but if you don't do that, then this variable will not be shared throughout the code.
Of course, you will actually put something inside that variable somewhere during the code, but since you defined this variable at the very beginning, it will be shared further anyway.
A variable holding null holds a reference to the "black hole" named null.
10 + 10 + null = null
Null is related historically to databases, http://en.wikipedia.org/wiki/Null_(SQL)
(Correct me if I'm wrong here)
A variable not initiated (unknown) is undefined.
regards,
/t