Create a single object - javascript

I want to create a single object. Does the below code make sense?
singleObj = new function () {
// act as a constructor.
};
Am I hurting any good practice?
I need a constructor. A simple object literal would not be useful here.

If you want just a single object, in that you are never going to make one again, an object literal works perfectly here.
var x = { };
Will give you an object.
In order for
var F = function() {
};
to give you an object you will need to invoke F
var x = new F();

you could try someting like:
var objCreate = function() {
var obj = {};
// do constructor logic
return obj;
};

Just create a new object and then populate it. You don't need a contrustor to do this.
var singleObject = {};
singleObject.value1 = "whatever";
If you really want to use a function, then you need to actually call it.
var singleObj = new (function () {
// act as a constructor.
})();
We can use a self executing function by creating a anonymous function function(){}, and immediately calling it with an empty argument set.

http://www.w3schools.com/js/js_objects.asp
//Used to create an object
personObj=new Object();
personObj.firstname="John";
personObj.lastname="Doe";
personObj.age=50;
personObj.eyecolor="blue";
//Used as a constructor for the object
function person(firstname,lastname,age,eyecolor)
{
this.firstname=firstname;
this.lastname=lastname;
this.age=age;
this.eyecolor=eyecolor;
}
//how to declare objects via constructor template
var myFather=new person("John","Doe",50,"blue");
var myMother=new person("Sally","Rally",48,"green");

Related

JS create custom object with self as parameter

I want to pass along "myEvent" through to "myFunction" at the end but in the object "Event", "myEvent" is undefined.
var myEvent = new Event(window,"click",myFunction,myEvent);
Event = function(target,type,func,parameter){
console.log(parameter) //undefined
var eventFunction = function(){
func(parameter)
}
this.delete = function(){
target.removeEventListener(type,eventFunction)
}
target.addEventListener(type,eventFunction);
}
myFunction(parameter){
console.log(parameter); // says undefined but I want the object "myEvent"
}
Sry for bad english
Use var that = this inside Constructor root level, then func(that) inside eventFunction. No need to explicitly pass along a reference to the newly created object, its already there in your constructor function.
If u need to explicitly pass along the myEvent reference, do:
var wrapper = {myEvent: {}};
wrapper.myEvent = new Event(...,wrapper.myEvent);

JavaScript inheritance why do I need to call both fun.call and prototype = new Obj( )?

function Base(x) {
this.x = x;
this.sub = new (function Sub() {
this.method = function() {
return function() {**this.super.x**}; // return an anonymous function that uses the outer x, but for reasons the anonymous function can't take parameters
}
});
}
var base = new Base(5);
console.log(base.sub.method()())
basically, in this example I'm trying to create an object Base who has a sub object sub, which has a 'method' that uses an anonymous function. The anonymous function needs the x but cannot take in any parameters..
Is there any way to access the this.x of Base?
At the beginning I tried the following.
This works well when Base is not inherited by other objects.
But in the following
"use strict";
function Base(x) {
var that = this;
this.sub = new (function Sub() {
this.method = function() {
return function() {
console.log(that); // displays Base *note[1]
return that.x;
}; // return an anonymous function that uses the outer x, but for reasons the anonymous function can't take parameters
}
});
}
function Other() {
Base.call(this); // why do I need to call Base.call(this) ?
this.setX = function(x) {this.x = x;}
}
Other.prototype = new Base();
var other = new Other();
other.setX(5);
console.log(other.sub.method()()); // otherwise undefined?
Base is extended by Other, after struggles I figured out I need to call Base.call(this); in order to make it works. Otherwise console.log(other.sub.method()()); will be undefined.
If I put a console.log(that) at *note[1], it will actually says the that is a Base object even though I construct it using var other = new Other(); I guess the problem would be solved if that is an Other object? What am I misunderstanding here?
My question is why do I need to call Base.call(this)? Why does it works after calling it? Is there any better solution to this situation?
If I understand you correctly you'd like Base to have a Sub and Sub is aware of the Base instance?
At the moment you're declaring the Sub type over and over again every time you create a Base, not the most effective way of doing it. Maybe try something like this:
function Sub(baseInstance){
this.baseInstance = baseInstance;
}
Sub.prototype.displayBaseX=function(){
console.log('base.x in sub:', this.baseInstance.x);
};
function Base(){
this.x = 22;
this.sub = new Sub(this);
}
You should not create an instance of Parent to set prototype of Child, use Object.create instead.
As for Parent.call(this, arguments) that is to re use the constructor function of Parent in Child when inheriting. More info about that can be found here: https://stackoverflow.com/a/16063711/1641941
The reason why your code doesn't work without Base.call(this); is because Base constructor defines and creates it's Sub type and instance. Not re using the Base constructor code when creating a Other type would cause the Other type not to have a Sub instance.
Constructor code deals with instance specific members and prototype can hold members that are shared by all instances. So usually behavior (functions) and a value for immutable default data members (numbers, string, boolean) can be found on the prototype.
I'm not exactly sure what you're end goal is here. But to solve your scope issue, this seems to work.
"use strict";
function Base(x) {
this.sub = new (function Sub(_this) {
this.method = (function(_this) {
return function() {
return _this.x;
};
})(_this);
})(this);
}
function Other() {
Base.call(this); // why do I need to call Base.call(this) ?
this.setX = function(x) {this.x = x;}
}
Other.prototype = new Base();
var other = new Other();
other.setX(5);
console.log(other.sub.method()); // otherwise undefined?
And a fiddle.

Is it possible to use a constructor in a Javascript object literal to avoid instantiation?

I have an object that needs certain properties to be set by execution instead of assignment. Is it possible to do this using a literal object notation?
I would like to be able to access the object's properties using this:
myObject.propertyName
...rather than this:
objInstance = new myObject();
objInstance.propertyName;
EDIT: to clarify, based on Bergi's answer, this is what I'm aiming to do:
var myObj = {
myInfo: (function() { return myObj.getInfo('myInfo'); })(),
getInfo: function() {
/* lots of execution here that would be redundant if done within myInfo */
}
}
// access the calculated property value
myObj.myInfo;
But this gives me the error myObj is not defined
I guess what you want is an IEFE, which you can put inside an object literal:
var myObject = {
propertyName: (function() {
var it = 5*3; // compute something and
return it;
}()),
anotherFunction: function() {…}
};
myObject.propertyName // 15
Maybe you also want to use the module pattern. Have a look at Simplest/Cleanest way to implement singleton in JavaScript?.
Thanks to Bergi to finding this, here is a final example what I wanted to do:
myObj = {
init: function() {
this.oneProperty = anyCodeIWant...
this.anotherProperty = moreCodeIWant...
// and so on
return this;
}
}.init();
myObj.oneProperty;
myObj.anotherProperty;
// and so on

Copy and modify similar object for instantiation javascript

I have an object that looks like
var customObject = function() {
this.property = "value";
};
customObject.prototype = new otherObject();
customObject.prototype.property2 = function() {};
etc. - it's much bigger than this.
I can successfully instantiate the object by writing new customObject().
Now I would like to create a rather similar object, although a little different. This involves modifying certain properties and perhaps even adding or removing some. As in the above example, I would like it to be invokable by writing new customObject2().
I thought I could simply do:
var customObject2 = new customObject();
customObject2.prototype = customObject.prototype;
customObject2.property = "modified value";
etc.
However, when I try to instantiate it by doing new customObject2() I receive an error, stating that the customObject2 is not a function.
I hope I could illustrate well enough as to what pattern I desire to create. What approach should I take to create such a pattern?
If customObject is not a host object (i.e. won't give you an illegal invocation error if you try to call it differently to expected) you can apply the constructor to a different this Object;
var customObject2 = function () {
customObject.call(this); // construct as if `customObject`
// now do more stuff
this.anotherProperty = 'foo';
};
customObject2.prototype = Object.create(customObject.prototype);
// inherit prototype but keep original safe
new customObject2();
Backwards compatible Object.create
function objectWithProto(proto) {
var f;
if (Object.create) return Object.create(proto);
f = function () {};
f.prototype = proto;
return new f();
}
I think this should answer your question. Basically, the new keyword is returning an object and not a function.
Why are you not using the same formula you used the first time? For example:
var customObject2 = function(){};
customObject2.prototype = new customObject();
customObject2.property = "modified value";
new customObject2(); // works!
All properties of customObject will be inherited by the instances of customObject2 through the prototype chain.

Dynamically control arguments while creating objects in javascript

I have multiple eatable classes in javascript eg: food, drinks, snacks.
Each of this class requires a different set of parameters. I have another factory class which creates an instance of the eatable item that is sent to it.
I am not able to figure out how can we dynamically select the eatable item and pass the arguments (which are in an array form) using this factory?
I have come up with two solutions -
Solution 1:
var factory = function(eatable, argumentList){
var obj = new eatable(argumentList);
return obj
};
This is a problem because argumentList is an array.
Solution 2
var factory = function(eatable, argumentList){
var obj = eatable.apply({}, argumentList);
return obj
};
this does not really create an object of the eatable type.
The effect that I really want
Say I am able to convert the argumentList into a js argument type object then -
var obj = new eatable(argumentList.toArguments());
obj instanceOf eatable; // should return true
Please help!
Ah, yes. I've encountered this problem before - you can't use new and apply together in JavaScript. A similar question has been asked before: Use of .apply() with 'new' operator. Is this possible?
The problem is quite apparent - new is a keyword, not a function; and apply can only be used on a function. If new was a function instead of a keyword then we could use it in conjuction with apply.
To understand how to do so let's create a function called new which does exactly what the keyword new does:
Function.prototype.new = (function () {
function Factory(constructor, args) {
return constructor.apply(this, args);
}
return function() {
Factory.prototype = this.prototype;
return new Factory(this, arguments);
};
}());
Now instead of calling a constructor as follows:
var object = new constructor(arg1, ...);
You can call a constructor as follows:
var object = constructor.new(arg1, ...);
What's the advantage of doing so you ask? Well it's simple really. Because new is now a function instead of a keyword you can use it in conjunction with apply as follows:
var object = Function.new.apply(constructor, [arg1, ...]);
Hence your eatable factory function now becomes:
var factory = function(eatable, argumentList) {
var obj = Function.new.apply(eatable, argumentList);
return obj;
};
Edit: If all your factory function does is take an eatable constructor and an argumentList and return new.apply(eatable, argumentList) then as Bergi pointed out in his comment you could define factory as follows instead:
var factory = Function.apply.bind(Function.new);
Hope this helped.
You can use Object.create to set up the prototype chain correctly:
function factory(eatable, argumentList){
var obj = Object.create(eatable.prototyope);
return eatable.apply(obj, argumentList) || obj;
}
This is basically what the new operator does.
You can define a function init to initialize the object .
function Eatable(){
}
Eatable.prototype.init = function(/** arg1, arg2, arg3 **/){
// initialize object
}
In factory function
var eatable = new Eatable();
eatable.init.apply(eatable, /** pass arguments array here **/);
return eatable;
You have to provide context to apply, The context is the object you are trying to apply the arguments to. The context you are currently passing {} is of type Object
var factory = function(eatable, argumentList){
var obj = eatable.apply(new Eatable(), argumentList);
return obj
};
I can not use factories with out polymorphism so if you didn't create those eatables in way they extend an Eatalbe object you will not be able to do it.
One more way to achieve this is as follows -
var _bind = Function.prototype.bind;
var factory = function(_constructor, _argumentList){
var obj = _bind.apply(_constructor, [null].concat(_argumentList));
return obj
};

Categories

Resources