is JS able to overwrite Object's Getter method? - javascript

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

Related

Working of static variables in JavaScript

A bit of confusion on how static works in javascript.
function StaticExample() {}
StaticExample.staticProp = "Hello"
console.log(StaticExample.staticProp) // "Hello"
Here I have created a function and then created a static variable staticProp (not if we can call it static though). This adds the field staticProp to the constructor field on StaticExample's prototype
Question 1: Is there a specific reason to this behaviour(field getting added to the constructor property)?
Now the constructor is rewritten as below.
StaticExample.prototype.constructor = {}
console.log(StaticExample.staticProp) // "Hello"
Even after that, when I tried to access StaticExample.staticProp, it provides the correct value of Hello
Question 2: From where the staticProp fetched, even when the constructor where it was initially added is overwritten.
StaticExample is an object. A function object, but an object nonetheless.
You assign a new property to it: StaticExample.staticProp = "Hello".
StaticExample also happens to have a property prototype.
The property StaticExample.prototype.constructor points to StaticExample.
Now, you can obviously access StaticExample.staticProp, because it's simply a property of an object that you assigned.
You can also replace the value of StaticExample.prototype.constructor with something else; now StaticExample.prototype.constructor doesn't point to StaticExample anymore. But StaticExample is still StaticExample and it still has the property staticProp that you created on it. You didn't replace the StaticExample object in any way. What you did replace was StaticExample.prototype.constructor, which is a different property of a different object.

javascript variables returns strange outputs

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

using a prototype on potentially empty parameters in JS

I'm updating a script that checks parameters like this:
if (config.param) {//do...}
This has lead to some issues in truthiness. I'd implemented a truthy() function as a prototype so as to be able to do the following:
if (config.param.truthy()) {//do...}
That seemed fine until I remembered that the config object only contains params being explicitly set. So config.value is usually undefined as opposed to false.
I'd added the prototype within an appropriate scope via String/Number/Boolean.prototype.truthy.
Is it possible to implement the prototype on the config object such that it will be able to return false on non-defined parameters?
Edit: My question is not about the truthiness (I can simply use a function), but instead how to implement a prototype on an object such that it is inherited by its properties, which may be different types or non-existent.
if ("param" in config && !!config.param) {//...
Or if you want to use a default value if undefined then
config.param = config.param || defaultValue
The whole problem with prototyping in this case is that falsey values will not get autoboxed to objects and so attempting to call methods of them will result in error.
Assuming that your params will all be different types of data, then your approach of adding prototype methods for Strings/Booleans/etc could work well. Then you could simply see if that property exists by doing
if (config.hasOwnProperty("param") && config.param.truthy() ) {//do...}
or if you're using dynamic property names
if( config.hasOwnProperty(param) && config[param].truthy() ) {//do...}

Attempt to delete prototype of HTMLElement fails

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.

javascript 'this' - how to find text name of object this points to

How to find the text description of what 'this' currently points to in javascript.
i have tried this.name but just get undefined.
this.toString() - I think that's the best you can get
EDIT: You can also try looping through the object's properties to see what it contains:
for (property in this) {
console.log(property);
}
If you're using Firebug you can use console.log(this). The console should then provide a clickable representation of whatever you've just logged, and clicking on it should take you to a more detailed explanation.
Well there's always typeof:
var type = typeof obj;
But, this is not foolproof as you will just get 'object' for objects...
Well, I'm still not entirely sure what you're wanting, but I've put this demo together, at JS Fiddle to give you an idea of a couple of the options available.
It rests on using:
$('#result').text(this.tagName.toLowerCase());
or
$('#result').text(typeof this);
Objects don't have names in JavaScript, it's as simple as that. A variable with a particular name could have an object as it's value, but that's as far as the relationship goes, the object retains no reference to the variable name that points to it. In fact, more than one variable may point to it. If a reference to an object is stored as a property on another object, you could iterate over that object's properties checking to see if the current property's value is the same object in the this value. For instance:
for (var k in someObj) {
if (this == someObj[k])
console.log(k + " points to this.");
}
I don't think there's a reason you'd ever need to do this, however.
No Firebug required (demo at http://jsfiddle.net/Y57ed/2/):
function usefulTypeof(obj) {
return obj === null ? "null" :
obj.constructor.toString().replace(/[^\w$\s]+/g, "").split(/\s+/)[1];
}

Categories

Resources