Steps:
Type in console of chrome:
[].anyName
This works Fine.
But when we type
{}.anyName
It gives error.
Because {} without context - ie in an assignment or as a parameter to a function, are just a block statement, and they return undefined.
When you enter {} to the console and click enter the result is undefined, as this was a block statement that just finished it's work and without an explicit return statement (you can't return from a block statement) returns undefined by default.
When you enter [] to the console and click enter the result is [], as this creates a new array.
[] this is an array which you can add a methods to the array prototype so when you type [].anyTime it's mean that you want to search in the array prototype for an anyTime method which does not exist so this will give you an undefined , but you can't access {}.anyTime in this way cause it is an object and you can access object like this var obj={}; obj.anyTime
Related
I'm using V8 (via Chrome) to test this. In Javascript, a code block evaluates to whatever the last value in the code block evaluates to. I wanted to see what would happen if I assigned a variable to an empty code block.
// example of code block evaluating to last value in the block
> {1;2;3};
3
// This won't work, it returns an empty object,
// not an empty code block.
> var emptyBlock = {};
> emptyBlock;
Object object
Eventually, I figured out how to specify that I want an empty code block, not an empty object.
> {;}
undefined
> {;;}
undefined
> {;;;;;}
undefined
Okay, beautiful, so an empty code block resolves to undefined. Right?
Not exactly!
> var emptyBlock = {;}
Uncaught SyntaxError: Unexpected token ';'
?! Now it is unclear whether the empty code block actually returns undefined, or something else entirely is at play. If it merely did evaluate to undefined, we would expect the above assignment to work.
Does anyone know why this is happening?
Eventually, I figured out how to specify that I want an empty code block, not an empty object.
This is largely determined by what is before the {, not after it.
Since you have an = before it, you are in a context where { is the start of an object literal. A ; is not allowed where a property name is expected, so the code errors.
You can't assign blocks. They aren't values, they are parts of the code structure.
Both of these seem demonstrably false. var codeBlockValue = {1;2;3}; for example works perfectly fine, and sets codeBlockValue to 3
No, it doesn't:
var codeBlockValue = {1;2;3};
This question already has answers here:
Does JavaScript have "Short-circuit" evaluation?
(3 answers)
Closed 6 years ago.
Why did javascript not throw a type error when I try to access a property that does not exist?
My code is below
var array = [];
var someBoolean1 = array[0] && array[0].hey;
The value of someBoolean turned out be 'undefinded'; I expect javaScript will throw a type error;
When I do
var array = [];
var someBoolean2 = array[0].hey;
The typeerror is thrown as expected.
But I do not understand why there is no type error in the first block of code.
Any idea?
Because you explicitly guard against the type error...
array[0] && array[0].hey
array[0] is undefined, so:
undefined && array[0].hey
undefined is falsey, so the right hand side is not evaluated, so the result of this expression is the left hand value undefined, which is assigned to someBoolean1.
Tangentially... to make such expressions less repetitive, usually this idiom is used:
var someBoolean1 = (array[0] || {}).hey;
If array[0] is undefined, {} will be used instead, and then the property .hey of that object will be accessed. If array[0] is an object with a property .hey, you'll get its value, otherwise you'll safely get undefined out of the entire expression.
No type error is thrown because your and operator is short circuiting, array[0] is undefined, which is not true, meaning javascript doesn't feel the need to check the second part of your and condition, and doesn't realize that there is a type error.
It happens because of the execution of && expression. array[0] happend to be evaluated to false so the rest of the expression is not evaluated.
if (false && "any another statement is unreachable")
then do something;
second expression not evaluated as array[0] false array[0].hey is not reached
var someBoolean1 = array[0] && array[0].hey;
Short Answer:
Because there is no element at the index 0 of array, and in more generic words, the property 0 is not defined in variable array. Therefore calling a property on something that is not defined would give you an error.
Long Answer:
Consider all JavaScript objects as dictionaries, and lets think that these dictionaries return us the values if we provide the keys that exist in them, otherwise nothing is returned.
Therefore when accessing an object property like myObject.propA (which is same as myObject["propA"]), if it exists in this object then the value of that property is returned and if not then undefined is returned, which denotes that this property is not defined in the myObject.
An array ([]) in JavaScript is also a type of object, and each member in the array is actually the property of that object. So a property in var arr = ["asd", "fgh"] can be accessed by arr[0] or arr["0"], which means that if property 0 of arr exists then it would return the value (in this case "asd"), otherwise would return undefined.
Providing all this, calling a property on something that is undefined is both illogical and illegal, so an exception is raised.
I am looking at the Mozilla Developers website on the concept of the delete operator. In the last sub section of the page referring to “Deleting array elements” two similar scripts are shown, but the only difference in the scripts is how they modified the array.
In the first script, I quite don’t understand why “if” statement does not run. My current understanding is that delete operator “removes the element of the array”. If I were to type trees[3] in the console, it would return undefined in the console.
var trees = ["redwood","bay","cedar","oak","maple"];
delete trees[3];
if (3 in trees) {
// this does not get executed
}
The second script seems to "mimic" the delete, but not literally. Undefined is assigned to trees[3]. It doesn’t make sense to me how the “if” block runs in this script, but the first example does not. Can anyone help me understand this JavaScript behavior?
var trees = ["redwood","bay","cedar","oak","maple"];
trees[3] = undefined;
if (3 in trees) {
// this gets executed
}
There is a huge difference between the two methods you are trying:
Method 1:
You are deleting, destroying, completely removing the key 3 in your array called tree, hence there is no 3 in tree left, and the if check returns false.
Method 2:
You are assigning a new value to the key 3, which is undefined, there is still 3 in tree, and the if check returns true.
In your second example the key 3 still exists. It just holds a value that happens to be undefined. It IS confusing, but that's just the way Javascript is.
The in operator just checks if the key exists, not if the value is defined.
If you were to output the whole arrays after each of your "deletions" the first example would display something like this:
["redwood", "bay", "cedar", 4: "maple"]
Whilst the second example would print out something like this:
["redwood", "bay", "cedar", undefined, "maple"]
So as you can see, in your first example the key is completely missing and it continues with the next key which is 4. In the second example the key still exists, but it's value is set to undefined.
There is a difference between undefined which is set by the user and undefined which the javascript engine returns once something is actually undefined, meaning doesn't exist.
javascript can tell the difference between the two.
So in your example, when you do this:
var trees = ["redwood","bay","cedar","oak","maple"];
trees[3] = undefined;
if (3 in trees) {
console.log("hi");
}
javascript can tell that property 3 exists, but it was set to undefined by the user.
to prove so you have the following:
if (5 in trees) {
console.log("hi");
}
the property 5 of the array was never created, javascript knows it's undefined
by lack of creation and regards it as a property which doesn't exist, and therefore doesn't display the "hi"
if(3 in tree) {
//Stuff that won't get executed
}
is in fact correct, the thing is that in operator in Javascript does not work like in python, it simply checks if an object has a proprety. An array in javascript has a proprety 0, just like a string has a proprety 2 with the value someString[2].
the difference between delete object[prop]; and object[prop] = undefined; can be seen through object.hasOwnProperty(prop); or iterating through values or props of the object.
Below is a simple code
var stop = true;
console.log(stop);
In console is show like this:
true
<. undefined // what this undefined, is it some reference.
I am wondering what is undefined
Every statement in JavaScript returns something.
When you enter console.log(true), true will be printed out and undefined will be returned.
undefined is one of the seven types in JavaScript that means something has been declared but not assigned a value.
undefined is the return value of console.log statements.
It's the return value of the console.log function.
The true that you see is a side-effect.
Suppose I have some variables:
var s = 's', i = 0, o = {}, a = [], n = null, nan = NaN, u;
How can I make any sense of when reading x.p will return undefined, and when it will throw a TypeError?
s.p; // undefined
i.p; // undefined
o.p; // undefined
a.p; // undefined
n.p; // TypeError!
nan.p; // undefined
u.p; // TypeError!
P.S. Are null and undefined the only weird values in this way? Are there others?
Edit
I'm aware that by declaring variables as I have, several of my values have been automatically wrapped by objects (e.g. Number), despite being primitives. Therefore I can treat them like "proper" objects (e.g. {}, []) and attempt to read their properties. But I can't find much explaining what is and isn't wrapped this way.
Yes, null and undefined are the only values that throw an exception when being used in a property access. The dot and bracket property accessors do invoke the internal CheckObjectCoercible function, which is defined as following:
The abstract operation CheckObjectCoercible throws an error if its
argument is a value that cannot be converted to an Object using
ToObject. It is defined by Table 15:
Table 15 — CheckObjectCoercible Results
Argument Type | Result
--------------+------------------
Undefined | Throw a TypeError exception.
Null | Throw a TypeError exception.
Boolean | Return
Number | Return
String | Return
Object | Return
null and undefined being the values that represent Nothing cannot be converted to objects ("wrapped" as you say). Notice that you could of course have an object with an existing property that throws on access, like
var o = {get p() { throw new TypeError("you may not access this"); }};
o.p // TypeError
When you're reading the property of something that's undefined. You're basing saying:
What is undefined of undefined? or in the case of null what is undefined of null ? Neither undefined nor null are objects, therefore you can't set or get properties on/from them. With that in mind, an error will be thrown.
When the object is null/undefined, it'll throw an error because it'll try to access a property of an object that does not exist in first place.
On the other cases, it'll try to access a property of an existing object and will return undefined because the property is not found.
Please note that almost everything in js is an object, as you can see here.
let's firstly start with
why undefined on:
var s='s';
You assigned s to string which is primitive type. Javascript is tricky here in one sense. Though primitive type, when you try to access the property by doing:
s.p
It firstly does this internally:
String(s)
and creates the object and then tries to see if it has that property which is, of course not defined and thus you get undefined. Almost similar things happen with numerical assignment and NAN.
For n=null:
If you do:
var n=null;
typeof n;//"object"
n.p// throws typeerror
In fact,null can be thought of special kind of object without any properties or method to represent absence of value and thus, you get typeerror when you try to access any properties of null.
a.p
o.p
Easily, you can see that you are trying to access the property of an object than is not defined or not built-in and thus it should say, undefined. You should be surprised to see other than that :D.
To add to the other answers here, there is an easy way to check if a property access will throw an exception. Simply loosely compare the value you're unsure of to null, like so:
if(x != null) { // note the LOOSE equality, rather than !==
// do something with x.prop
}
The reason this works is that only null and undefined * throw errors on property access, and they are only loosely equal to each other. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_when_to_use_them.
* There is also a case where some JS objects can apparently "emulate" being undefined, in which case they also are loosely equal to null and undefined.