javascript assigning new object as object property - javascript

I have an object that looks like this:
var BigObject = {
'CurrentInt': 0,
'CurrentBool': false,
'CurrentObject': {}
}
And then, I declare SomeObject like this:
var SomeObject = {
'SomeString': "",
'SomeInt': 0
}
These two definitions are for the objects when they're in their initial state, sort of like a type definition I guess. Now I want to assign a new SomeObject to BigObject['CurrentObject']. I tried this:
BigObject['CurrentObject'] = new SomeObject();
But it's not working. At the moment, I just do a straight assignment by reference BigObject['CurrentObject'] = SomeObject; and then when I need to reset the values of SomeObject, I just run a function that redeclares each property of SomeObject in its initial stage.
But how can I use the new keyword to create a reusable object type that's a property of BigObject.
Thanks.

new can only be used with a function, to run it as constructor:
function SomeObject() {
this.SomeString = "";
this.SomeInt = 0;
}
What you have done is equivalent to:
var SomeObject = new Object();
SomeObject.SomeString = "";
SomeObject.SomeInt = 0;

If you're defining a type, you should use a constructor function:
var SomeObject = function() {
this.someString = "";
this.someInt = 0;
}
var BigObject = function() {
this.currentInt = 0;
this.currentBool = false;
this.currentObject = new SomeObject();
}
Once you've defined these constructors, you can new them (create instances):
var myBigObject = new BigObject();
console.log(myBigObject.currentObject);

Use JavaScript classes.
function SomeObject() { }
SomeObject.prototype.someString = "";
SomeObject.prototype.someInt = 0;
function BigObject(){ this.currentObj = new SomeObject; }
BigObject.prototype.currentInt = 0;
BigObject.prototype.currentBool = false;
BigObject.prototype.currentObj = null;
var a = new BigObject;
a.currentObj instanceof SomeObject; // true

Related

loop throught a function properties, possible?

I want to loop through a functions properties, here is my attempt:
var hen = function a() {
this.name = "euler henrique";
this.ID = 55530;
this.REC = 0302;
this.nick = "any will do";
}
for (var p in hen) {
console.log(hen[p]);
}
but that doesn't work, even if hen was an instance of a. Any suggestion?
A quick solution might be to add the elements to an array, as a property of the parent object. For instance
var hen = function a() {
this.name = "euler henrique";
this.ID = 55530;
this.REC = 0302;
this.nick = "any will do";
this.info = [this.name, this.id, this.REC, this.nick];
}
And then looping through this array the way you would any array.
var myHen = new Hen();
for(var x = 0; x < myHen.info; x ++)
{
info = myHen.info[x];
if(info)
{
console.log(info);
}
}
Not sure if this what you were going for, let me know if this isn't what you need and i'd be happy to share some other ideas.
You can do it if you create an instance of the object:
var Hen = function() {
this.name = "euler henrique";
this.ID = 55530;
this.REC = 0302;
this.nick = "any will do";
}
var myHen = new Hen();
for (let prop in myHen) {
if (myHen.hasOwnProperty(prop)) {
console.log(prop);
}
}
You can create an object using the function constructor: new YourFunctionName();
From MDN: "The hasOwnProperty() method returns a boolean indicating whether the object has the specified property as its own property (as opposed to inheriting it)."

How to make a function assigning a value using assignment operator in jquery

Having the following function :
function ObjDataSet () {
this.header = "";
this.dataIdx = 0;
this.DataRows = [];
this.CountRow = 0;
}
....
ObjDataSet.prototype.NameString = function(argIdx, argName, argValue) {
var arrObj = this.DataRows[argIdx-1];
arrObj[argName] = argValue;
this.DataRows[argIdx-1] = arrObj;
};
And I am using this function like this after declaration:
var dataSet = new ObjDataSet();
dataSet.NameString(1, "CUST_KIND",document.searchForm.CUST_KIND.value);
But I would like to use this function like this using assignment operator :
dataSet.NameString(1, "CUST_KIND") = document.searchForm.CUST_KIND.value;
To use assignment operation, How to change "NameString" function?
I don't want to assign a value as a argument of function.
Thank you.
You cannot do what you are asking. The left hand side of an assignment must be a variable or a property of an object. The closest you can do is this:
dataSet.NameString(1).CUST_KIND = 'value';
Which assumes dataSet.NameString(1) returns an object that can have a property assigned to it. Here is a full demo:
var dataSet = setup();
// Log DataRows before and after assigning:
console.log( dataSet.DataRows );
dataSet.NameString(1).CUST_KIND = 'value';
console.log( dataSet.DataRows );
//////
// Prepare dataSet object with `DataRows[0] = {};`
function setup ( ) {
function ObjDataSet () {
this.header = "";
this.dataIdx = 0;
this.DataRows = [];
this.CountRow = 0;
}
ObjDataSet.prototype.NameString = function(argIdx, argName) {
return this.DataRows[argIdx-1];
};
const dataSet = new ObjDataSet;
dataSet.DataRows[0] = {};
return dataSet;
}

How can I make privileged JS methods?

I want to be able to call sub-functions that work with private data. Currently I have this:
var myFunction4 = function() {
this.secret1 = 0;
this.secret2 = 0;
var that = this;
this.iterate1 = function(){
return that.secret1++;
}
this.iterate2 = function(){
return that.secret2++;
}
this.addSecrets = function(){
return that.secret1 + that.secret2;
}
return {
iterate1: this.iterate1,
iterate2: this.iterate2,
addSecrets: this.addSecrets,
}
};
The bad thing about this is that to call one of the methods, I have to do:
myFunction4().iterate1();
Which executes myFunction4() every single time I want to access a method. Not only is this inefficient, but it resets secret1 each time so I can't iterate it. I've tried using the new operator, but that exposes secret1 and secret2, and it messes up the ability to nest functions deeply.
var myFunction3 = function() {
this.secret1 = 0;
this.secret2 = 0;
this.iterate1 = function(){
return this.secret1++;
}
this.iterate2 = function(){
return this.secret2++;
}
this.addSecrets = function(){
return this.secret1 + this.secret2;
}
};
var f3 = new myFunction3();
f3.secret1; // exposes the secret!
See the console logs at the bottom of this JSFiddle for more examples.
How can I have a function with both private and public vars/methods which retain their values and don't need to be called multiple times?
While the other answers are absolutely fine and correct, there is one more issue to consider when emulating OOP behaviour in javascript.
The function execution context issue will bite us hard when we will try to use a public method as a e.g. async. callback.
The magical this will point to a different object then we expect in the OOP world.
Of course there are ways to bind the context but why to worry about this after we define the 'class' in a non OOP js ;)
Here is a simple solution to this: Do not use this. Let the closure refactor this out ;)
var myFunction4 = function() {
// we could inherit here from another 'class' (object)
// by replacing `this` with e.g. `new SuperClass()`
var that = this;
// 'private' variables
var secret1 = 0;
var secret2 = 0;
// 'public' variables
that.somePublicVar = 4;
// 'private' methods
var somePrivateMethod = function(){
secret2 = 77;
that.somePublicVar = 77;
}
// 'public' methods
that.iterate1 = function(){
return secret1++;
}
that.iterate2 = function(){
return secret2++;
}
that.addSecrets = function(){
return secret1 + secret2;
}
return that;
};
var f = new myFunction4();
console.log( f.iterate1() ); // 0
console.log( f.iterate1() ); // 1
console.log( f.secret1 ); //undefined
console.log( f.somePublicVar ); //4
Try that (closures power!):
var myFunction3 = function() {
var secret1 = 0;
var secret2 = 0;
this.iterate1 = function(){
return secret1++;
}
this.iterate2 = function(){
return secret2++;
}
this.addSecrets = function(){
return secret1 + secret2;
}
};
var f3 = new myFunction3();
now only the methods are exposeds
Edited version:
If you don't wanna execute the main function every time you call sub-method, you can change a bit your approach and use the power of IIFE (immediately-invoked function expression)
var myFunction4 = (function() {
var secret1 = 0;
var secret2 = 0;
var iterate1 = function(){
return secret1++;
}
var iterate2 = function(){
return secret2++;
}
var addSecrets = function(){
return secret1 + secret2;
}
return {
iterate1: iterate1,
iterate2: iterate2,
addSecrets: addSecrets
}
}());
Then you can use this:
myFunction4.iterate1();
myFunction4.iterate2();
myFunction4.addSecrets();
Hope this helps you
I generally only use the factory pattern to create objects unless I absolutely need to have the performance benefits of prototypical inheritance.
Using the factory pattern also means you don't have to deal with the ever changing value of this in different contexts.
var factory = function() {
// internal private state
var state = {
secret1: 0,
secret2: 0
}
function iterate1(){
return state.secret1++;
}
function iterate2(){
return state.secret2++;
}
function addSecrets(){
return state.secret1 + state.secret2;
}
function __privateMethod() {
// this is private because it's not on the returned object
}
// this is the public api
return {
iterate1,
iterate2,
addSecrets
}
}
// create a secret module
var secret = factory()
console.log(
secret.iterate1(), // 0
secret.iterate2(), // 0
secret.addSecrets(), // 2
secret.secret1, // undefined
secret.secret2 // undefined
)
// you can even create more with the same factory
var secret2 = factory()
Why don't you try Revealing Module Pattern
var myFunction4 = function() {
var secret1 = 0,
secret2 = 0,
iterate1 = function(){
return secret1++;
},
iterate2 = function(){
return secret2++;
},
addSecrets = function(){
return secret1 + secret2;
};
// public functions and properties
return {
iterate1: iterate1,
iterate2: iterate2,
addSecrets: addSecrets,
}
}();
myFunction4.iterate1(); // is available
myFunction4.secret2; // is private and not available outside of myFunction4
Hope it helps
A basic pattern:
var myFunction = function() {
var that = this;
var secret1 = 0;
var secret2 = 0; // private
this.public1 = 0; // public
this.iterate1 = function(){
return secret1++;
}
this.iterate2 = function(){
return secret2++;
}
this.addSecrets = function() { // public
return privateMethod();
}
var privateMethod = function() { // private
return secret1 + secret2;
}
return this; // return function itself!
};
var myFn = new myFunction();
myFn.public1 // 0
myFn.secret1 // undefined
myFn.addSecrets();
I recommend you to read the excellent Learning JavaScript Design Patterns by Addy Osmani.
What I understand from your explanation as per your second snippet is that you need a sharedPrivate among the instantiated objects. You can not do this with classical object creation patterns like constructor, factory or module. This is possible by taking a private variable under closure in the prototype of the constructor so that it doesn't get reset each time an object is created and at the meantime the instantiated objects are provided with necessary methods to access, modify and share it privately.
function SharedPrivate(){
var secret = 0;
this.constructor.prototype.getSecret = function(){return secret}
this.constructor.prototype.setSecret = function(v){ secret = v;}
this.constructor.prototype.incrementSecret = function(){secret++}
}
var o1 = new SharedPrivate();
var o2 = new SharedPrivate();
console.log(o1.getSecret()); // 0
console.log(o2.getSecret()); // 0
o1.setSecret(7);
console.log(o1.getSecret()); // 7
console.log(o2.getSecret()); // 7
o2.incrementSecret()
console.log(o1.getSecret()); // 8
And another method of getting a similar result would be
function SharedPrivate(){
var secret = 0;
return {getS : function(){return secret},
setS : function(v){secret = v},
incS : function(){secret++}
};
}
sharedProto = SharedPrivate(); // secret is now under closure to be shared
var o1 = Object.create(sharedProto); // sharedProto becomes o1.__proto__
var o2 = Object.create(sharedProto); // sharedProto becomes o2.__proto__
o1.setS(7); // o1 sets secret to 7
console.log(o2.getS()); // when o2 access it secret is still 7
o2.incS(); // o2 increments the secret
console.log(o1.getS()); // o1 can access the incremented value

Effect of "new" in JavaScript

I have written some code I found in a video, and it looks something like this:
var clientX = clientX || {} ;
clientX.MyClass = function(initialValue){
var var1 = initialValue;
var publicMembers = {
get_var1 : function(){
return var1;
}
};
return publicMembers;
}
var result = new clientX.MyClass("val1");
alert(result.get_var1());
clientX.instance = new clientX.MyClass("val2");
alert(clientX.instance.get_var1());
clientX.instance2= new clientX.MyClass("val3");
alert(clientX.instance2.get_var1());
The thing is, after deleting the "new" keyword when I use : var result = new clientX.MyClass("val1"); Nothing is changed, so why the author chose to use it? What's the effect?
The MyClass function makes no use of this and has an explicit return value, so the use of new has no practical effect whatsoever.
the new keyword is used as a piece of pseudoclassical instantiation, wherein a constructor object has properties attached to the keyword "this" but no return value is ever written.
var Car = function(){
this.color = 'blue';
this.make = 'toyota';
this.model = 'camry';
}
now, writing var x = new Car() will add the following lines to the interpretation:
var Car = function(){
var this = {}; //added by new
this.color = 'blue';
this.make = 'toyota';
this.model = 'camry';
return this; //added by new
}

javascript calling the function from prototype

I am learning javascript. When I call pictureArrayAdd method I receive error Picture.pictureArrayAdd is not a function. Why?
window.onload = init;
//window.picture = new Array();
function init() {
var button = document.getElementById("addButton");
button.onclick = addPicture;
}
function Picture() {};
Picture.prototype = {
pictureArray: [],
pictureArrayAdd: function(newImage) {
this.pictureArray.push(newImage);
return this
}
}
var addPicture = function() {
var textInput = document.getElementById ("pictureName");
var newPicture = textInput.value;
Picture.pictureArrayAdd(newPicture);
}
You have to initialize an instace of your object:
var addPicture = function() {
var textInput = document.getElementById ("pictureName");
var newPicture = textInput.value;
var pic = new Picture();
pic.pictureArrayAdd(newPicture);
}
Besides - just a tip -, you can use a optional parameter on your constructor, like this:
function Picture(newImage) {
if (newImage != undefined) {
this.pictureArrayAdd(newImage);
}
};
So you have a shortcut to your pictureArrayAdd function:
var pic = new Picture("picture1.png");
See it working here.

Categories

Resources