If a is undefined, this works:
if(window.a) {}
while this throws an error:
if(a)
Can someone explain why?
window.a is a property of window and it's undefined. a is a variable, and it's undeclared.
To use a variable, you should first declare it using the var statement. Since you didn't declare a, the interpreter raises an error. Object properties are not needed to be explicitly declared in order to use them. Crockford writes in The Good Parts:
If you attempt to extract a value from
an object, and if the object does not
have a member with that name, it
returns the undefined value instead.
Related
I'm currently playing around with "const" variable in javascript and here is my code
My question is, why is "const x" undefined when used with "console.log", but it is defined when used on its own?
p.s. -- I understand that both global "const, let" do not become the property of "window" object, unlike global "var". But I am unsure as to whether this played any role in the code above.
You're seeing undefined because console.log() function actually returns you that.
Notice how x is still 123 when you query just x?
The assignment operation for const x = 123; is undefined because it returns you undef as well.
What browser/version are you using? Trying it in both FF65 and Chromium71, console.log( x ); indeed gives me 123 ...
Recently I investigated a situation in which a programmer inadvertently passed undefined into addEventListener, thus:
window.addEventListener('load', undefined);
No error was thrown. It's as if JavaScript is willing to invoke undefined. But what in the world is undefined()? I have tried all sorts of things, e.g.:
console.log(undefined() === null);
console.log(typeof undefined());
but I never get anything back.
Edit added for clarity: My original question was based on a mistake, as I had not set my Developer tools to log errors to the console. The above two commands (but not the call to addEventListener) DO throw errors in a browser, as answers and comments below indicate.
It's as if JavaScript is willing to invoke undefined.
No, addEventListener is specified to ignore null, which JavaScript’s undefined is converted to. undefined is never called.
Further proof that JavaScript is not willing to invoke undefined, in a browser:
> undefined()
Uncaught TypeError: undefined is not a function
at <anonymous>:1:1
You can do something like this to find the type of passed arguments:
var myVar;
Object.prototype.toString.call(myVar);
and it will return "[object Undefined]"
same for other use cases like if myVar is a string as below:
var myVar = 'It is a string';
Object.prototype.toString.call(myVar);
it will retrun "[object String]"
It will return:
Undefined is not a function
console.log(typeof undefined());
If you run it console on a browser it will return undefined not a function. Undefined does not have any value unlike null which is an object.
null means that something exists, but has been told it has no value.
undefined means that thing has not been given a value, usually because it hasn't been declared/initialized.
In Javascript, undefined is a primitive. It's falsey, so it evaluates to False if used in conditional.
Javascript is not a strongly typed language, so there's nothing to check that a callback function is a function until it's called. In fact Javascript doesn't care how many arguments are passed or what their type is, everything's just dumped in when a function is invoked, and it's up to the function how to handle the arguments.
For example in many enumerable methods, they pass back to you (index, value, array). It doesn't matter if your function looks for these values or assigns them a temporary variable, they're still passed. Both a.forEach(function(index){}) and a.forEach(function(){}) actually have access to all 3 of the variables mentioned.
I'm new here and new to Javascript. I got a strange problem here when I output the values to the console. As far as I know In both these cases the name, and the color is the properties of object car to access them we need to use this.propertyName or object.propertyName, but when I output those values to the console without using this or object name, 1st console.log returns an empty string and the other one returns the uncaught reference error. are they pointing to the window object? then in both the cases, it should return a uncaught reference, can somebody here please clarify this.. thanks in advance. :)
var car = {
name : "ford",
color:"red",
log : function(){
console.log(name);
// outputs an empty string
console.log(color);
// Returns error (this.js:8 Uncaught ReferenceError: color is not defined)
}
}
car.log();
Try console.log(this.name) and console.log(this.color).
Additional Information from MDN
When a function is called as a method of an object, its this is set to
the object the method is called on.
In the following example, when o.f() is invoked, inside the function
this is bound to the o object.
Source: MDN
The reason you don't get a ReferenceError when outputting name is that browsers have a built-in global called name: It's the name of the current window. But they don't have a built-in global called color, so you get the error.
To access name and color on your object when you use car.log(), you'd use this.name and this.color.
yes you are correct both should have thrown uncaught reference but wait ....
actually there is a property on window which is .. yeah ... name
so actually you console that property of window.. ie window.name
.. second one is just correct .. uncaught reference
everyone:
as we all know, getting a nonexistent value from Object will got a "undefined", is there any way to throw an error instead of return a undefined?
for instance:
var a= {example:"example"};
//do something here
a.b //error throw instead of "undefined"
thx very much for helping.
Object.define property has a way to specify the get and set methods
look at the link below
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
Object class has a method "hasOwnProperty" which could also be used to check if a property exists or not before trying to access it
ES6 comes with Proxy Objects which will help you overload the dot operator. What this means is that you can invoke a function when you retrieve a property. This will allow you to check if the property is defined and if it isn't "throw" an error. Hope this helps. More info here
Looking at the above example, if you are you trying to initialize the property "b" on the object a with a value after "a" has been defined, then you could just as easily do the following:
var a= {example:"example"};
//do something here
a.b = 'some value';
a.b //now an error is not throw
Most Objects can be re-defined even after they have been initialized. Properties and methods can be added and removed once objects have been initialized.
I say most, because it is possible to prevent objects from being extended/altered (using Object.preventExtension method).
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/preventExtensions
I was trying to delete .insertBefore(); of HTMLElement.prototype but when I check for it, instead of an undefined value, it returns the actual function? Why?
console.log(HTMLElement.prototype.insertBefore); // function insertBefore() { [native code] }
delete HTMLElement.prototype.insertBefore;
console.log(HTMLElement.prototype.insertBefore); // function insertBefore() { [native code] }
Can you explain why this isn't working. I tried this on my own constructor and it worked, but for the built in ones, it didn't.
You cannot use DELETE like that:
http://perfectionkills.com/understanding-delete/
Property attributes
Every property can have zero or more attributes from the following set — ReadOnly, DontEnum, DontDelete and Internal. You can think of them as flags — an attribute can either exist on a property or not. For the purposes of today’s discussion, we are only interested in DontDelete.
Built-ins and DontDelete
So this is what it’s all about: a special attribute on a property that controls whether this property can be deleted or not. Note that some of the properties of built-in objects are specified to have DontDelete, and so can not be deleted. Special arguments variable (or, as we know now, a property of Activation object) has DontDelete. length property of any function instance has DontDelete as well.
Seriously man, read that article. It has a ludicrously clear and concise explanation of all this!
Note: even though they have the dontDelete attribute set, you can still overwrite it:
HTMLElement.prototype.insertBefore = '';
// or
HTMLElement.prototype.insertBefore = null;
// or
HTMLElement.prototype.insertBefore = undefined;
The browser implementation(s) probably have that property set as non-configurable.
There may be a greater chance that it is writable though:
HTMLElement.prototype.insertBefore = null;
console.log(HTMLElement.prototype.insertBefore); // null
Keep in mind that objects like HTMLElement are host objects, and therefore don't necessarily follow all the same rules of regular JavaScript objects.
For example, trying to delete a non-configurable property when in strict mode should throw an error, but testing this in Chrome, no error is thrown.
http://jsfiddle.net/YrvE4/2/
Seen here, you if you create your own custom property, you can delete that just fine:
"use strict";
HTMLElement.prototype.custom_property = 'value'; // new property
console.log(HTMLElement.prototype.custom_property); // value
try {
delete HTMLElement.prototype.custom_property;
} catch (e) {
console.log(e);
}
console.log(HTMLElement.prototype.custom_property); // undefined
http://jsfiddle.net/YrvE4/3/
HTMLElement.prototype, like all of DOM, is a "host object", which is basically something provided by the ECMAScript environment that isn't defined in the ECMAScript spec. Host objects have few rules they have to follow: it is perfectly allowable for [[Delete]] to do nothing, even if Object.getPropertyDescriptor has [[Configurable]]: false.