How is better to check parameters object in javascript? - javascript

Most of time I use something like this:
function(obj) {
obj = obj || {};
// do stuff
var foo = obj.foo;
}
But my coworkers played a little bit with console.time/timeEnd and ensured me that
if (obj)
var foo = obj.foo;
is faster (code may be more complicated, it's only example).
But, as for me, 1st variant looks better. But we created additional empty object every time (when no parameters passed). I would like to hear what do you think guys. What method do you use?

The first method is appropriate when you need a valid object in obj for the rest of your code and you want to assure there is a valid object in just one place in the code.
The second method is appropriate when you just want to check if obj was passed or not and do something different in your code depending upon that condition. A more robust check would be:
if (typeof obj === "object")
So, these are different techniques that accomplish different goals and are mostly used in different circumstances.
So, the answer is that "it depends upon what the rest of your code is doing and on what you're really trying to accomplish in your code". There is no one answer that is always correct.
A common design pattern for your first technique is used when you have an optional object with optional properties and you want to fill in default values for missing properties or even if the whole object was not passed:
function doSomething(obj) {
var defaults = {timeout: 2000, caseSensitive: false, waitTime: 400};
var options = Object.assign({}, defaults, obj);
// safely use options object in the rest of this function
}
This technique also safely works on a copy of the passed object so the caller's object is never modified.

The first one is slower because if obj is missing it will go through creating an object. The second one just does an check and an assignment so it will be quicker but you won't have the presence of obj. If you ever depend on the presence of obj then use the first one, if you just refer to foo then use the second one.
However...in all honesty you shouldn't fret over optimizations like this, instead do what you feel is clearer and easier to read.

I would recommed to use the second method for checking whether object is defined or not. A better way would be to check for object that i think is
if(typeof object !== undefined)
as it gives a clear understanding what we are trying to do in the if block

Related

Object unexpectedly being modified after push into array

I have what seems like it should be a simple operation. For each bridgedSection, I check for a potentialSection with an id that matches the bridged.referenceSection
Then I take that result, parse the HTML on the object with Cherio, make a slight modification (using an id for testing), and then store both the bridgedSection and the modified result on an object, then push that object to the array.
If I log the new object BEFORE pushing, I get the correct object values. If I log it from the array I get incorrect values only for reference.section. bridgedSection is fine, but reference.section matches across all entries in the array.
To say that I'm thoroughly flummoxed is an understatement. Can anyone shed some light on what I am (clearly) doing wrong?
var sectionCount = 0;
bridgedSections.forEach(bridged => {
var obj = potentialSections.find(obj => obj._id == bridged.referenceSection);
$ = cheerio.load(obj.html);
$(".meditor").html(bridged._id);// dropping the id here so it's easy to see if it was updated
obj.html = $.html();
obj.rand = Math.floor(Math.random() * 1000); // can't seem to add to obj either
var thisSection = {
referenceSection: obj,
bridgedSection: bridged,
}
console.log(thisSection) // correct value logged
currentSections.push(thisSection);
sectionCount++;
});
console.log(currentSections);
// this logs an array of the correct length but each
// {}.referenceSection is identical to the last entry pushed above
To try to clarify what both of the above folks are saying, the JavaScript language (like many others) has the concept of references, and makes very heavy use of that concept.
When one variable "refers to" another, there is only one copy of the value in question: everything else is a reference to that one value. Changes made to any of those references will therefore change the [one ...] underlying value (and, be reflected instantaneously in all of the references).
The advantage of references is, of course, that they are extremely "lightweight."
If you need to make a so-called "deep copy" of an array or structure or what-have-you, you can do so. If you want to push the value and be sure that it cannot be changed, you need to make sure that what you've pushed is either such a "deep copy," or that there are no references (as there obviously are, now ...) to whatever it contains. Your choice.
N.B. References – especially circular references – also have important implications for memory management (and "leaks"), because a thing will not be "reaped" by the memory manager until all references to it have ceased to exist. (Everything is "reference counted.")
And, all of what I've just said pretty much applies equally to every language that supports this – as most languages now do.
Javascript is passes function parameters by reference. This means the following happens:
derp = {a:1}
function passedByRef(param){
param['a'] = 2;
}
passedByRef(derp)
console.log(derp['a']) // 2
So when you pass a json object to a function, if you modify said object in the function it will change the original object. You probably want to make a deep copy of bridged before you assign it to thisSection because if you modify the version of bridged later on in thisSection it will modify the original object.
Here is a post that talks about cloning objects or you could look into something like immutable js
I think you need to look into Javascript deep copy.
You are modifying the original object when you modify the second assigned variable, because they are pointing to the same object. What you really need is to duplicate the object, not simply making a pointer to it.
Take a look at this:
https://scotch.io/bar-talk/copying-objects-in-javascript#toc-deep-copying-objects

How to get the object "address" in javascript?

Well, I am not sure if I describe the problem clearly, currently I am using ExtJS to do some developing, I saw some objects are "singleton", such as "Ext.Viewport", In C++, I can get the address of the object to see if they are actually same object, in Python, I can use "id" function to get the hash code of the object, and In Java I have similar built-in function "hashCode" to check if the objects are really same object, is there similar ways in javascript for this? so if there are some functions or operator in javascript, then I can tell if the object in ExtJS defined as "singleton" is really referencing to the same object.
You don't need anything so complicated. If two values are the same object, then they will be equal.
var foo = {};
var bar = foo;
alert(foo == bar);
If they are different (even if identical) objects, they won't be.
var foo = {};
var bar = {};
alert(foo == bar);
Your question is not very clear, but I'll try to answer.
Javascript itself does not use unique identifiers for each object by default. You could add this if you wanted to.
Depending on your requirements, you could also use the typeof operator to compare the type.
ExtJs however, does use unique id's (either id or itemId) and also allows you to get the class name of the object that your using. So you could do this easily in ExtJs.
The answer depends on whether you are comparing the type of object, or the actual object instance itself.
This other SO answer may be beneficial
I think that I'm understanding you... but, did you check this JavaScript comparator ?
=== - equal value and equal type
!== - not equal value or not equal type
reference: Javascript comparators
If you want to know if two object references refer to the same single object instance, use ==.
If you want to do a deep comparison of the referenced objects to see if the objects contain all the same values, even if they are not the same object instance, use Lodash's _.isEqual(a, b) method.
could also convert both to json, and use something like jsonDiff: https://github.com/pkafel/json-diff

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.

How to serialize an object in JavaScript?

For example I have class:
function Test() {
}
Test.prototype = {
'setTest' : function(test) {
this.test = test;
}
}
var test = new Test();
Test.setTest('test');
I want to save object test in database.
How to serialize object test to string? (methods, variables, etc)
Simple with json
JSON.stringify( test );
In this case, for the question you're asking, there really isn't a way to do what you want. The problem with your request lies in "serializing everything attached to the object, including functions".
Serialization normally only occurs for data, because executables are usually machine bound, in that they are compiled for a given machine, based on certain characteristics. Now, it's reasonable to say that javascript functions just require a javascript interpreter, because javascript is write-once, run-everywhere. But when people write serializers, because all serializers tend to work the same, we write them for data only. In this case, the industry standard is JSON, which is an object-data only serializer.
There are three solutions that avail themselves to you at this point:
Write your own serialier/deserializer that encapsulates functions. This can be tricky, because not all javascript engines will give you access to the source.
Write your own re-loading mechanism that generates a specific new initialized type on each restore, and save the typename as one of the properties on serialization. That way the initialization of each variable gives you the methods, and then merging with the data gives you the complete object.
Store each function as a string and eval it on the fly as you need it. This is incredibly tricky, and is quite prone to errors. I can think of no case where this becomes helpful, because it's quite fragile. However, it is an option, and cannot be overlooked.
I know that 3 is a sub-answer for 1, so you can consider it that there are only two useful answers.
I know that superficially this works on Chrome and IE9, so it should work everywhere the majority of users are likely to use it:
var abc = function(thing) { return thing; }
abc.toString();
// gives "function(thing) { return thing; }" on the command line
So you can certainly serialize the methods as strings in place of the actual method, but you're going to need to create a duplicate object so you can capture every element on the source object (I think, rather than replacing them in place).
Hopefully this helps you think about the problem some more, and maybe to realize you don't need to serialize the methods (nobody ever does that I know of, not reasonably).
The best way to do this is to write your own serialize method which creates a JSON object with attributes, based on your getters. Normally you define a getter per attribute. So it should work for most cases (so you don't have to define a serialize method for each class).
function serialize(obj) {
var serialized = {};
for(var prop in obj) {
if (obj.hasOwnProperty(prop) && typeof obj[prop] == 'function') {
if (/^get.*/.test(prop)) {
var value = obj[prop]();
var name = prop.replace('get', '');
if (typeof value === 'object') {
serialized[name] = this.serialize(value);
continue;
}
serialized[name] = value;
}
}
}
return serialized;
};
To reset your attribute values back to the class you have two options:
Create a function in your class which creates a valid object instance based on the serialized JSON.
Create a unserialize method and map the JSON with your class using the setters.
Example:
function unserialize(obj, emptyClass) {
// Check emptyClass for setters and map the data from obj to it.
return 'class instance';
}
Typically, you'd do this with JSON, which is widely supported across browsers/languages/libraries/etc. The only hangup is that JSON does not support functions – but do you really need to serialize those?
I've had to support functionality similar to this before. I ended up saving the name of the function as a string and serializing it as JSON. Then when I come back to the client, I execute the function using a helper like the one posted in this question.
If anyone has a better way to solve this problem, I'd want to see it!
I recently had to find a solution for this problem. I'm sure it can be improved upon.
First I created a module for instantiating the "serialisable" object.
function MyObj(serialised){
this.val = "";
if(serialised){
var unserialised = JSON.parse(serialised);
for (var i in unserialised) {
this[i] = unserialised[i];
}
}
}
MyObj.prototype.myMethod = function () { return this.val;};
module.exports = MyObj;
you of course have to consider error handling and other validations.

Javascript - Passing arguments to function

I've always passed arguments to a function like so:
setValue('foo','#bar')
function setValue(val,ele){
$(ele).val(val);
};
Forgive the silly example. But recently I have been working on a project that has some functions that take a lot of arguments. So I started passing the arguments through as an object (not sure if that's the correct way to put that), like so:
setValue({
val:'foo',
ele:'#bar'
});
And then in the function:
function setValue(options){
var value = options.val;
var element = options.ele;
$(element).val(value);
};
My question is, is there a better way to do that? Is it common practice (or okay) to call these 'options'? And do you typically need to 'unpack' (for lack of a better term) the options and set local vars inside the function? I have been doing it this way in case one of them was not defined.
I'm really looking to not create bad habits and write a bunch of code that is ugly. Any help is appreciated and + by me. Thanks.
I do the exact same thing, except I don't declare a new variable for each option inside the function.
I think options is a good name for it although I shorten it to opts.
I always have a "default" object within the function that specify default values for each available option, even if its simply null. I use jQuery, so I can just use $.extend to merge the defaults and user-specified options like this: var opts = $.extend({}, defaults, opts);
I believe this is a great pattern. I've heard an options object like this referred to as a "builder object" in other languages (at least in the context of object creation). Here are some of the advantages:
Users of your function don't have to worry about what order the parameters are in. This is especially helpful in cases like yours where the method takes a lot of arguments. It's easy to get those mixed up, and JavaScript will not complain!
It's easy to make certain parameters optional (this comes in handy when writing a plugin or utility).
There are some pitfalls though. Specifically, the user of your function could not specify some of the options and your code would choke (note that this could also happen with a normal JS function: the user still doesn't have to supply the correct arguments). A good way for handling this is to provide default values for parameters that are not required:
var value = options.val || 0;
var element = options.ele || {};
$(element).val(value);
You could also return from the function immediately or throw an exception if the correct arguments aren't supplied.
A good resource for learning how to handle builder objects is to check out the source of things like jQueryUI.
I realize this question is a year old, but I think the cleanest way to pass an arbitrary number of arguments to a JavaScript function is using an array and the built in apply method:
fun.apply(object, [argsArray])
Where fun is the function, object is your scope/context in which you want the function to be executed and the argsArray is an array of the arguments (which can hold any number of arguments to be passed.
The current pitfall right now is that the arguments must be an array (literal or object) and not an array-like object such as {'arg' : 6, 'arg2' : "stuff"}. ECMAScript 5 will let you pass array-like objects, but it only seems to work in FireFox at the moment and not IE9 or Chrome.
If you look at the jQuery implementation, it uses an options class to handle most of the arbitrary-number-of-parameters functions, so I think you are in good company.
The other way is to test for arguments.length, but that only works if your arguments are always in the same order of optionality.
It's worth remembering that all functions have a bonus parameter called arguments that is an object very much like a JS array (it has length but none of the array functions) that contains all the parameters passed in.
Useful if you want to pass in a range of parameters (e.g.
function Sum() {
var i, sum = 0;
for (i=0; i < arguments.length; i++){
sum+=arguments[i];
}
return sum;
};
If this isn't the case and you just have a lot of parameters, use the params object as you've described.
Nothing wrong with that practice.
"Options" seems like as good a name as any.
You don't need to "unpack" them, but if you'll be accessing the same item several times, it will be a little more efficient to reference them in local variables because local variable access is generally quicker than property lookups.

Categories