Running multiple javascript object methods together - javascript

I am trying to write a little helper class for my ajax chat system i am working on just trying to add basic functions that i may need.
var strings = {
filterWords: ["fool", "dumb", "arse"],
removeSpecialChars: function (str) {
return str.replace(/[^\w\s]/gi, '');
},
killSpace: function (str) {
return str.replace(/\s/g, '');
},
reduceSpace: function (str) {
return str.replace(/\s+/g, ' ');
},
allowLetsAndNums: function (str) {
return str.replace(/[^A-Za-z0-9]/g, ' ');
},
allowLets: function (str) {
return str.replace(/[^A-Za-z]/g, ' ');
},
allowNums: function (str) {
return str.replace(/[^0-9]/g, ' ');
},
wordFilter: function (str) {
var rgx = new RegExp(this.filterWords.join("|"), "gi");
return str.replace(rgx, "****");
}
}
What i am finding is i may need to run multiple methods together i am asking whats the best practise to do this without resulting with below?
alert(strings.wordFilter(strings.reduceSpace(strings.allowLets("efgwge #£235%^#£ fool you a dumb arse432345$%^"))));
Thanks

You could make this a fluent interface, allowing code like this:
var x = new Validation("efgwge #£235%^#£ fool you a dumb arse432345$%^");
alert(x.allowLets().reduceSpace().wordFilter().result());
// alerts "efgwge **** you a **** ****"
Your main code would need to be:
var Validation = function(str) {
this.str = str;
filterWords = ["fool", "dumb", "arse"]
this.removeSpecialChars = function () {
this.str = this.str.replace(/[^\w\s]/gi, '');
return this;
};
this.killSpace = function () {
this.str = this.str.replace(/\s/g, '');
return this;
};
this.reduceSpace = function () {
this.str = this.str.replace(/\s+/g, ' ');
return this;
};
this.allowLetsAndNums = function () {
this.str = this.str.replace(/[^A-Za-z0-9]/g, ' ');
return this;
};
this.allowLets = function () {
this.str = this.str.replace(/[^A-Za-z]/g, ' ');
return this;
};
this.allowNums = function () {
this.str = this.str.replace(/[^0-9]/g, ' ');
return this;
};
this.wordFilter = function () {
var rgx = new RegExp(filterWords.join("|"), "gi");
this.str = this.str.replace(rgx, "****");
return this;
};
this.result = function(){
return this.str;
};
}
Live example: http://jsfiddle.net/fb7en/

You could extend the String prototype:
String.prototype.removeSpecialChars = function () {
return this.replace(/[^\w\s]/gi, '');
}
String.prototype.killSpace = function () {
return this.replace(/\s/g, '');
}
var foo = "This is my§$% String";
​document.write​(foo.removeSpecialChars​().killSpace());​

You could add the functions to the String.prototype so you can call the functions like this:
String.prototype.killSpace = function() {
return this.replace(/\s/g, '');
}
String.prototype.reduceSpace = function () {
return this.replace(/\s+/g, ' ');
}
"foo bar".reduceSpace().killSpace(); // => returns foobar
Only downside to this is that you can't iterate over a string with a for..in loop then because it will list the method as a member and there's currently no cross-browser way to make it non-iterable (IE doesn't support it).

You might consider a chainable API for your Object:
var StringFilter = {
_string: '',
string: function (string) {
this._string = string || '';
return this;
},
filterWords: ["fool", "dumb", "arse"],
removeSpecialChars: function () {
this._string = this._string.replace(/[^\w\s]/gi, '');
return this;
},
killSpace: function () {
this._string = this._string.replace(/\s/g, '');
return this;
},
reduceSpace: function () {
this._string = this._string.replace(/\s+/g, ' ');
return this;
},
allowLetsAndNums: function () {
this._string = this._string.replace(/[^A-Za-z0-9]/g, ' ');
return this;
},
allowLets: function () {
this._string = this._string.replace(/[^A-Za-z]/g, ' ');
return this;
},
allowNums: function () {
this._string = this._string.replace(/[^0-9]/g, ' ');
return this;
},
wordFilter: function () {
var rgx = new RegExp(this.filterWords.join("|"), "gi");
this._string = this._string.replace(rgx, "****");
return this;
},
select: function () {
return this._string;
}
};
StringFilter
.string("efgwge #£235%^#£ fool you a dumb arse432345$%^")
.allowLets()
.reduceSpace()
.wordFilter()
.select();

Related

Call a function from inside a function?

I have the following code:
var A = function (id) {
var elem = document.getElementById(id);
function text () {
return "Hello world";
}
this.other = function(){
console.log(text());
}
}
What if I wanted to add the other function from outside and still call the text() function like this:
(function(A){
A.prototype.other = function() {
console.log(text());
}
})(A);
Is there any way to do that? I mean without having to change function text(){} to this.text=function(){}
You could attach text() method to A function which is still an object and then use it in A.prototype.other like this.
var A = function(id) {
this.id = id;
}
A.text = function() {
return "Hello world";
}
A.prototype.other = function() {
return this.id + ' ' + A.text();
}
var a = new A(123);
console.log(a.other())

Javascript function does not return the right value

So i have this code:
function Class1() {
this.i = 1;
var that=this;
function nn() {
return 21;
}
this.aa = function() {
nn();
};
this.bb = function() {
this.aa();
};
this.cc = function() {
this.bb();
};
}
var o = new Class1();
var b=o.cc();
alert(b); //undefined
But when the alert is fired, I get an undefined error and not 21, Does the private method can not use a return? Thanks!
When using the function() {} syntax to define a function, you always explicitly need to return the value, i.e. not only from nn, but from all intermediate functions as well.
function Class1() {
this.i = 1;
var that = this;
function nn() {
return 21;
}
this.aa = function() {
return nn();
}
this.bb = function() {
return this.aa();
}
this.cc = function() {
return this.bb();
}
}
var o = new Class1();
var b = o.cc();
alert(b); // "21"
Apart from the answer above, the 'this' context seems weird in your functions. Maybe you are better of with arrow functions if you dont want to bind the this context to each function. I also think that it is better to actually separate private and public functions when using a 'class' like this.
function Class1() {
var _nn = function () {
return 21;
}
var _aa = function () {
return _nn();
}
var _bb = function () {
return _aa();
}
var cc = function () {
return _bb();
};
return {
cc
};
}
var o = new Class1();
var a = o.cc();
console.log(a);
Much easier to understand that it is only cc that is a public function.
So with arrow function it would instead look like this, and you can use the Class1 this context inside of your private functions without doing
var that = this; or using bind.
function Class1() {
this.privateThing = 'private';
var _nn = () => { return this.privateThing; };
var _aa = () => { return _nn(); };
var _bb = () => { return _aa(); };
var cc = () => { return _bb(); };
return {
cc
};
}

Set value into object with function (java script)

When I used getFullName, getFirstName and getLastName work ok, but I can't use set functions setFullName, setLastName, setFirstName. My code:
var Person = function(firstAndLast) {
var fn=firstAndLast.split(' ');
var fstr=fn.join(' ');
var frn=fn[0];
var lsn=fn[1];
this.getFullName=function(){return fstr;};
this.getFirstName=function(){return frn;};
this.getLastName=function(){return lsn;};
this.setFirstName=function(a){fn[0]=a;};
this.setLastName=function(b){fn[1]=b;};
this.setFullName=function(c){fn=c.split(' ');};
};
What about this:
var Person = function(firstAndLast) {
var self = this;
this.fn = firstAndLast.split(' ');
this.frn = this.fn[0];
this.lsn = this.fn[1];
this.getFullName=function(){return self.fn.join(' ');};
this.getFirstName=function(){return self.frn;};
this.getLastName=function(){return self.lsn;};
this.setFirstName=function(a){self.frn=a; self.fn[0]=a;};
this.setLastName=function(b){self.lsn=b; self.fn[1]=b;};
this.setFullName=function(c){
self.fn = c.split(' ');
self.frn = this.fn[0];
self.lsn = this.fn[1];};
};
See this fiddle
If you have a lot of Person objects, you should consider moving the getter/setter functions to the class prototype:
var Person = function(firstAndLast) {
this.fn = firstAndLast.split(' ');
this.frn = this.fn[0];
this.lsn = this.fn[1];
};
Person.prototype.getFullName = function() {
return this.fn.join(' ');
}
Person.prototype.getFirstName = function() {
return this.lsn;
}
Person.prototype.getLastName = function() {
return this.lsn;
}
Person.prototype.setFirstName = function(a) {
this.frn=a;
this.fn[0]=a;
}
Person.prototype.setLastName = function(b) {
this.lsn=b;
this.fn[1]=b;
}
Person.prototype.setFullName = function(c) {
this.fn = c.split(' ');
this.frn = this.fn[0];
this.lsn = this.fn[1];
}
See updated fiddle

how to call function using name such as "function someName(){}"?

I have a name of a private function in JavaScript as a string, how do I call that function?
var test = function () {
this.callFunction = function(index) {
return this["func" + index]();
}
function func1() { }
function func2() { }
...
function funcN() { }
}
var obj = new test();
obj.callFunction(1);
func1 and friends are local variables, not members of the object. You can't call them like that (at least not in any sane way).
Define them with function expressions (instead of function declarations) and store them in an array.
var test = function () {
this.callFunction = function(index) {
return funcs[index]();
}
var funcs = [
function () {},
function () {},
function () {}
];
}
var obj = new test();
obj.callFunction(0);
As your code stands, the functions are not present as properties of the instance. What you need to do is create them as properties of the context.
var test = function () {
this.callFunction = function(index) {
return this["func" + index];
}
this.func1 = function() { }
this.func2 = function() { }
...
}
var obj = new test();
obj.callFunction(1)();
you can use eval
var test = function () {
this.callFunction = function(index) {
return eval("func" + index + '()');
}
function func1() {
return 1;
}
function func2() {
return 2;
}
function funcN() { }
};
var obj = new test();
obj.callFunction(2);
eval is evil
You can use a private array of functions:
var test = function() {
var func = [
function() { return "one" },
function() { return "two"; }
]
this.callFunction = function(index) {
return func[index]();
}
}
var obj = new test();
var ret = obj.callFunction(1);
console.log(ret);​
​
http://jsfiddle.net/V8FaJ/

Javascript Metaprogramming

Is there a way to specify something similar to the following in javascript?
var c = {};
c.a = function() { }
c.__call__ = function (function_name, args) {
c[function_name] = function () { }; //it doesn't have to capture c... we can also have the obj passed in
return c[function_name](args);
}
c.a(); //calls c.a() directly
c.b(); //goes into c.__call__ because c.b() doesn't exist
Mozilla implements noSuchMethod but otherwise...no.
No, not really. There are some alternatives - though not as nice or convenient as your example.
For example:
function MethodManager(object) {
var methods = {};
this.defineMethod = function (methodName, func) {
methods[methodName] = func;
};
this.call = function (methodName, args, thisp) {
var method = methods[methodName] = methods[methodName] || function () {};
return methods[methodName].apply(thisp || object, args);
};
}
var obj = new MethodManager({});
obj.defineMethod('hello', function (name) { console.log("hello " + name); });
obj.call('hello', ['world']);
// "hello world"
obj.call('dne');
Almost 6 years later and there's finally a way, using Proxy:
const c = new Proxy({}, {
get (target, key) {
if (key in target) return target[key];
return function () {
console.log(`invoked ${key}() from proxy`);
};
}
});
c.a = function () {
console.log('invoked a()');
};
c.a();
c.b();
No.

Categories

Resources