What is the best way to control if an object should not be created in Javascript? I have been searching, and it seems that the only way to not returning this, is returning an object. This does not work:
var Example = function( params ) {
if(!params){
return null;
}
};
var foo = new Example(); // foo is not null
I donĀ“t want foo to be instanceOf Example.
Thanks, best regards.
Basically you're creating an object using your function as a constructor but the return value from a constructor is ignored.
What you can do is make a factory function like so
http://javascript.info/tutorial/factory-constructor-pattern
Example = function()
{
this.Value = 10;
}
Example.Create = function(params ) {
if(!params){
return null;
}
return new Example();
}
var result = Example.Create();
alert(result);
jsFiddle here : https://jsfiddle.net/CanvasCode/3pab7cco/
Or you can add a bool value to your function and then check that after you have created your object
var Example = function( params ) {
this.isValid = true;
if(!params){
this.isValid = false;;
}
};
var example = new Example();
if(!example.isValid){ example = null; }
alert(example);
Related
Let's say that a hany any object, that return a string for example.
And I have the following:
function alterString(str){
return `${str} was altered!`
}
//I want call my method as if it were be inside the return type
let new_string = object.returnString().alterString();
I've already did this in C#, but I don't even know the name to research
String.prototype.alterString=function(){
return `${this} was altered!`;
}
var obj = {
returnString : function(){ return 'Hi'; }
};
let new_string = obj.returnString().alterString();
Or else you can add alterString() directly into returnString() as below.
var obj = {
returnString : function(){
this.text = "Hey";
}
};
obj.returnString.prototype.alterString = function(){
return `${this.text} was altered!`;
}
let new_string = new obj.returnString().alterString();
Hi I'm trying to implement a LinkedList in Javascript. When i assign a value to my node it doesn't seem to store it when I use my getter. For example:
var Node =function() {
var _data;
var _next ={};
var that = this;
that.getData = function() {
return _data;
};
that.setData = function(data) {
that._data = data;
};
that.getNext = function() {
return _next;
};
that.setNext = function(next) {
that._next = next;
};
return that;
};
Will not work with:
var nodeObj = new Node();
nodeObj.setData("hello");
console.log(nodeObj.getData());
_data is not the same as that._data, you must do this:
that.getData = function() {
return that._data;
};
OR you could do this instead:
that.setData = function(data) {
_data = data;
};
the benefit of the second approach being that you're simulating a private variable (because you cannot do nodeObj._data in the second case but you can in the first)
also var that = this; is unnecessary, you can simply do this._data in this case.
For your case here, you can assume that if you're calling a function like yourObject.someFunction(), then within someFunction the value of this equals yourObject. (And this isn't always true in javascript but since you're starting off you should think about it this way for now. If you pass a function to another function as a variable and then call it then this wouldn't be the case).
I'm a JS beginner. I have defined a function on my Backbone model as follows.
myFunction: function () {
return {
firstAttr: this.model.get('value-attribute')
};
}
It is available to me as this.myFunction.
From somewhere else in the code, I want to extend this.myFunction to return another attribute. In other words, I'd like it to return a dict with two attributes: { firstAttr: 'something', secondAttr: true }.
How can I do this?
I've tried:
this.myFunction().secondAttr = true;
but I know that's the wrong thing to do.
Assuming your model prototype looks like
var MyModel = Backbone.Model.extend({
myFunction: function () {
return {
// I assume you work directly on a model
// the principle would be the same with a wrapper object
firstAttr: this.get('value-attribute')
};
}
});
you can either mask your method on a model by model basis like this:
var m = new MyModel({'value-attribute': 'attr, the first'});
console.log(m.myFunction());
m.myFunction = function () {
var res = MyModel.prototype.myFunction.call(this);
res.secondAttr = true;
return res;
};
console.log(m.myFunction());
See http://jsfiddle.net/V8zt2/ for a demo
Or dynamically modify your prototype to alter all instances :
var f = MyModel.prototype.myFunction;
MyModel.prototype.myFunction = function () {
var res = f.call(this);
res.secondAttr = true;
return res;
};
var m = new MyModel({'value-attribute': 'attr, the first'});
console.log(m.myFunction());
http://jsfiddle.net/V8zt2/1/
How about modifying your myFunction to :
myFunction : function () {
var i,
obj = {};
for (i=0; i< arguments.length;i++){
obj['attribute'+(i+1)] = this.model.get(arguments[i]);
}
return obj;
}
This way you can send keys of model, that you want to be in the returned object as arguments to myFunction.
I have worked out a method to access an objects private properties by creating a method that returns those properties. However I would like to create a single function that can return any object property based on the string argument passed.
Here is an example of what I am trying to do:
function MyObj() {
var myProp = 10;
this.getProp = function( propName ) {
return( propName ); // THIS IS WHERE I AM STUCK
};
}
MyObj.prototype.getMyProp = function() {
return this.getProp( 'myProp' );
};
var myObj = new MyObj();
console.log( myObj.getMyProp() );
As you can see from this example the string "myProp" is returned not the variable. I can't use this[propName] as I'm not in the right scope and I can't use the that/self technique to access the scope.
How do return an object property using a string?
One simple solution would be to wrap your private variables in an object like this:
function MyObj() {
var privateVars = {
myProp: 10
};
this.getProp = function( propName ) {
return privateVars[propName];
};
}
MyObj.prototype.getMyProp = function() {
return this.getProp( 'myProp' );
};
var myObj = new MyObj();
console.log( myObj.getMyProp() ); // 10
Update: it appears that eval will work in this case, too, but I wouldn't recommend it:
function MyObj() {
var myProp = 10;
this.getProp = function( propName ) {
return eval(propName);
};
}
MyObj.prototype.getMyProp = function() {
return this.getProp( 'myProp' );
};
var myObj = new MyObj();
console.log( myObj.getMyProp() ); // 10
I have a part of plugin which uses private variables and exposes public method :
JSBIN 1
function myWorld()
{
var myPrivate=1;
this.do1=function (){alert(myPrivate);} ;
}
var a=new myWorld();
a.do1() //1
alert(a.myPrivate); //undefined (as it should be)
But I want to prevent doing this again : new myWorld();
The only option I know is with object literal :
JSBIN 2
var myWorld=
{
myPrivate:1,
do1:function (){alert(this.myPrivate);}
}
alert(myWorld.myPrivate); //1 ( ouch....)
myWorld.do1() //1
Question
How can encapsulate private fields and still prevent uses from myWorld to be instanced >1 times ?
Closures are a great tool to define the scope:
var myWorld= (function(){
var myPrivate = 1;
return {
do1:function (){alert(myPrivate);}
}
}());
myWorld.do1();
You might want to check out the free Learning JavaScript Design Patterns book
Try something along these lines:
(function(){
var instanciated = false;
window.myWorld = function() {
if( instanciated) throw new Error("myWorld can only be instanciated once!");
instanciated = true;
var myPrivate = 1;
this.do1 = function(){alert(myPrivate);};
}
})();
You can hide the private variable inside an IIFE:
var myWorld = (function() {
var myPrivate = 1;
return { ... };
}());
var a = new function myWorld()
{
var myPrivate=1;
this.do1=function (){alert(myPrivate);} ;
}
This makes myWorld available only inside the function. If you don't event want it accessable there, then remove the name.
You could use a singleton pattern to maintain one instance of the object. Something like:
(function (global) {
var _inst;
global.myWorld = function () {
if (_inst) throw new Error("A myWorld instance already exists. Please use myWorld.getInstance()");
_inst = this;
};
global.myWorld.prototype = {
do1: function() {
console.log("do1");
}
};
global.myWorld.getInstance = function() {
if (_inst) return _inst;
return new myWorld();
};
}(window));
var world = new myWorld();
var world2 = myWorld.getInstance();
console.log(world === world2); // true
var world3 = new myWorld(); // throws Error