Objects with their own intrinsic value. Another way to do getters - javascript

I wanted to be able to create an object that had it's own intrinsic value. That way I could use it in an expression as if it was a regular variable. It turned out to be quite easy - so easy I am wondering if I am missing something. All it seems to take is to make sure the object contains a method "valueOf". Like so:
var p = {
a: 12;
valueOf: function(){return this.a+12}
}
alert(p/3); // =8
It's probably a good idea to include a "toString" method too. What seems to be happening is that without the valueOf method, a reference to the object goes up the prototype chain until it finds the method on Object, which just returns "object Object". By providing a local one, the method can return anything.
It seems to work in all browsers that I tried.
It is really another way to provide a getter-like functionality. But a little better because getters can only be applied to properties of objects. This way you can use the object itself.
What do you think? Is this safe? Any pitfalls?

Well I started using this pattern and found one issue. If you create an object p like the one above, you have to guess how the interpreter will view a reference to the object.
For example, if P is used in arithmetic expression, it calls the object's valueOf() method to get its value. But when you try to access a property of p such as p.a, then it treats p as an object and retrieves the property as you expect.
In a getter, by contrast, accessing p.a when there is a getter on p would first run the getter and then try to get the property 'a' of the result. Subtly different, but important.
It's all quite correct and seems to "guess" correctly what to do. But using the pattern does rely on knowing this behavior, which AFAIK is not documented anywhere.

Related

JavaScript Object Syntax & Notation

I've been using JavaScript for a short period of time, and have found myself interested as to whether or not there is any correlation between the . syntax used for referencing children of an object, and functions such as console.log.
And was interested whether functions such as this, were in a way objects behind the scenes, with log being a method inside of a console object, and if I am just referencing the child of an object.
Or another example, the .length method, is this just a hidden property of the object or array you are referencing.
Apologies if this is poorly worded, I was struggling to write down my train of thought, and I would be incredible appreciative if anyone could let me know if this is how methods such as these are structured, or if I am thinking of them in completely the wrong way.
Notice how you can access the length property on a string. While string is a primitive, the length property actually exits on a wrapper object that is created temporarily when we try to read .length.
Arrays and other collections have this property, because they are objects themselves.
Hope this helps to clarify a bit!
console.log is not a function, per se. The function is the log property on the console object. console is an object with many methods:
To access it's method, just like to access any property of a JS object, you can use dot notation or square bracket notation
var log = console.log;
log('hello');
var logSquare = console['log'];
logSquare('hello');
// or just do
console['log']('hello');
Except for primitives, everything in JS is an object.

What's the difference between str.fun() / str.fun / fun(str) in JavaScript?

I tried googling but couldn't find a precise answer, so allow me to try and ask here. If the question does not seem proper, please let me know and I'll delete it.
In JS you've got three different way of writing certain build in functionalities:
str.length
str.toString()
parseInt(str)
I wonder if there is a reason behind these different ways of writing. As a new user I don't grasp why it couldn't be streamlined as: length(str) / toString(str) / parseInt(str) or with dot formulation.
I however think if I do know the reason behind these differences, it would give me a better understanding of JavaScript.
Length is one of the attributes of string in JavaScript. Hence you use string.length to get the length of the string.
toString is a function for string objects, hence we use stringobj.toString().
parsInt(str) is a global function which takes string as a parameter.
JavaScript is object-oriented, so there are functions or procedures which require first an object to use as this in their bodies. str.length is a property, both syntactically and semantically. It doesn't require any parameters and represents some quality of the object. obj.toString() is a method (a function attached to an object), which doesn't represent any characteristics of the object, but rather operates on its state, computes some new values, or changes the state of the object a lot. parseInt(str) is a "global" function, which represents an operation not attached to any type or object.
Under the hood, these three ways may be well implemented with just calling a function, passing this as the first parameter (like C# does, for example). The semantic difference is the important one.
So why not use just the third syntax, like for example PHP does? First, it doesn't bloat the global environment with lots of functions which only work for one specific case and type, allowing you to specify any new function you want without breaking the old functionality. Second, it ecourages you to use object-oriented concepts, because you can already see working objects and methods in the language, and can try to make something similar.
And why isn't parseInt a method? It can as well be str.toInt() without any issues, it's just the way JavaScript designers wanted it to be, although it seems also a bit logical to me to make it a static method Number.parseInt(str), because the behaviour of the function is relevant more to the Number type than the String type.
JavaScript is based around objects. Objects have properties (e.g. a User object may have name and age properties). These are what define the user and are related to the user. Properties are accessed via dot-notation or brackets notation (to access Eliott’s age, we’ll use either eliott.age or eliott['age'] — these are equivalent).
These properties can be of any type — String, Number, Object, you name it — even functions. Now the proper syntax to call a function in JS is to put round brackets: eliott.sayHello(). This snippet actually fetches Eliott’s sayHello property, and calls it right away.
You can see Eliott as a box of properties, some of which can be functions. They only exist within the box and have no meaning out of the box: what would age be? Whose age? Who’s saying hello?
Now some functions are defined at the global level: parseInt or isNaN for instance. These functions actually belong to the global box, named window (because legacy). You can also call them like that: window.parseInt(a, 10) or window.isNaN(a). Omitting window is allowed for brevity.
var eliott = {
name: 'Eliott',
age: 32,
sayHello: function () { console.log('Hello, I’m Eliott'); }
};
eliott.name; // access the `name` property
eliott.age; // access the `age` property
eliott.sayHello; // access the `sayHello` property
eliott.sayHello(); // access the `sayHello` property and calls the function
sayHello(eliott); // Reference error: `window.sayHello` is undefined!
Note: Some types (String, Number, Boolean, etc.) are not real objects but do have properties. That’s how you can fetch the length of a string ("hello".length) and reword stuff ("hello, Eliott".replace("Eliott", "Henry")).
Behaviour of these expressions is defined in ECMAScript grammar. You could read the specification to understand it thoroughly: ECMAScript2015 specification. However, as pointed out by Bergi, it's probably not the best resource for beginners because it doesn't explain anything, it just states how things are. Moreover I think it might be too difficult for you to be able to grasp concepts described in this specification because of the very formal language used.
Therefore I recommend to start with something way simpler, such as a very basic introduction to JavaScript: JavaScript Basics on MDN. MDN is a great resource.
But to answer your question just briefly:
str.length is accessing a property of the str object.
parseInt(str) is a function call
str.toString() is a call of a function which is a property of the str object. Such functions are usually named methods.
Functions and methods are in fact very similar but one of the differences (except for the obvious syntax difference) is that methods by default have context (this) set to refer to the object which they're part of. In this case inside of toString function this equals to str.
Note: Accessing a property (as in str.length) could in effect call a getter function but it depends on how the object is defined, and is in fact transparent for the user.

define method on built-in type in javascript

Problem for example: In general null object means additional class which handle cases when object not found etc.
In Ruby you can also define method for Nil class. And I want realise something similiar in js.
That's what gives me hope typeof(null) //=> object, but in same time null instanceof Object //=> false. So defining method for Object gives me nothing.
So the final question: is there any hacks to define method on built-in types?
Please don't.
That's really bad form and will lead to nasty, hard to find, bugs.
Or if you do - do it with greatest of cares.
Read here for more: http://perfectionkills.com/extending-built-in-native-objects-evil-or-not/
You can do that in javascript too.
I am not sure whether I understand your question.But here is my take on it.
alert(typeof(null));//gives you object.
MyObject=Object.create(null);
This means
MyObject doesn't inherit from anywhere
MyObject has no properties at all.

is there a generic, explicit primitive -> object cast in JavaScript?

I have the following puzzle (works in NodeJS):
console.log((42).toFixed);
console.log(Object.getPrototypeOf(42));
While the first line does show [Function: toFixed], the second fails with TypeError: Object.getPrototypeOf called on non-object. This, I believe, is the correct behavior as for the spec (but puzzling for anyone how believes that everything is an object in JavaScript).
Now I would like to write a method like console.dir that outputs all the properties of an object, including those coming from prototypes, and including those that are in fact accessible from primitive values.
Of course, the crux of the matter is that JavaScript tries to be smart and does a behind-the-scenes sleight-of-hand, casting the primitive value 42 to something akin to new Number( 42 ). The trick is done when you access a certain named property on the primitive value, but not when the value is an argument to getPrototypeOf (I believe it really should).
In order to reach my goal, I could go and determine the type of the primitive value in case getPrototypeOf should fail, and then pick from a hopefully limited number of possibilities (Number, String, Boolean, ...) the right one. this does not even sound difficult.
But it does feel a little ... wrong. What feels much better is a built-in / custom method cast_as_object that converts a primitive to an object no matter what its type is, preferably in some generic and future-proof way. Is that possible?
(n.b. It's trivial to go from type name to prototype when type names are unique and the set of primitives is small and closed—but I'm asking this question with the hope that answers will help people to better understand that theoretically simple yet practically intricate beast that is JavaScript's object model).
#Ken Kin—asking for a feature is asking a question, no?—not sure what you're implying here.
#charlietfl—i believe i stated benefits in my text, to quote: "I would like to write a method like console.dir that outputs all the properties of an object". as it stands, console.dir will simply echo the stringification (what a word) of a primitive value (and, oddly, new Object( 42 ) results in {}).
the solution turns out to be quite simple, as brought forth by #GameAlchemist: after doing
value = new Object( primitive_value )
you can apply Object.getOwnPropertyNames and Object.getPrototypeOf to value, allowing to retrieve all properties on the object and the prototype chain.

What is the correct way to initialise an empty property of an object in JavaScript

I have an object that with properties, 1 of those properties prop2 will only be initialised later and added to this object when its ready.
I want to show it as a property of the object purely for human readability so that when I look at the code later I will know that it exists and will/can be used.
So my question is what is:
What is the correct way to initialise an empty property of an object
in JavaScript
myObject = {
prop1: 'somevalue',
prop2: '' <---- ''|null|undefined|false|0|{} what is correct
}
I am assuming it depends on the type that will be used, and I realise that anything actually works, I am interested in the best practice way.
Fiddler: http://jsfiddle.net/gamelodge/DWCEa/
I usually use null for this purpose. It is distinct from undefined (does not exist) and satisfies the requirement that the variable exists but has no value.
The usual way is to use null.
undefined would work as well, but a) it's longer b) it's not a keyword c) too many people use typeof to test for property existence. It also has a little different notion.
As you said, depending on the expected type you might as well use any other appropriate value. Empty objects or strings are less convential, especially since objects have lots of construction overhead. Do not use them if you don't plan to use (extend) them later.

Categories