Javascript Singleton communication definition required - javascript

I made a object to keep my functions became singleton, using that, i made sample methods to call and communicate each other.. but i don't get any appropriate results..
any one correct me, the singleton the way i defined here...
my sample codes:
var obj = window[obj] || {}; //singleton
obj.nameIt = function(name){
this.name = name;
this.getName = function(){
return this.name;
}
}
obj.sayIt = function(name){
this.name = name; var that = this;
this.sayHello = function(){
console.log("say" + this.name);
that.getName();//how to get result from nameIt?
}
}
var x = obj.nameIt("af");
console.log(x.getName());//says "undefined" - how to call it?
var y = obj.sayIt("xy");
console.log(y.sayHello());//says "undefined" - how to call it?
jsfiddle here

Your code does not return anything.
obj.nameIt = function(name){
this.name = name;
this.getName = function(){
return this.name;
}
return this;
}
obj.sayIt = function(name){
this.name = name; var that = this;
this.sayHello = function(){
console.log("say" + this.name);
return that.getName();
}
return this;
}

Related

Write getters as a prototype

I'm working on making performance updates on my javascript code.
In Firefox I got this warning:
mutating the [[Prototype]] of an object will cause your code to run very slowly; instead create the object with the correct initial [[Prototype]] value using Object.create
I wrote some scripts to prove this, and the results are great: without mutation a simple script runs 66% faster.
But I have trouble converting my code without mutation, I can't write the getters:
This is what I have now:
// Class
function FooBar(options) {
this.options = options;
}
// Prototype
FooBar.prototype = {
// Getters
get a() {
return this.options.a;
},
get b() {
return this.options.b;
},
get ab() {
return this.options.a + this.options.b;
},
// Methods
displayOptions: function() {
console.log(this.options);
}
};
// Code
var options = {
a: 'foo',
b: 'bar'
};
var fooBar = new FooBar(options);
console.log(fooBar.a);
console.log(fooBar.b);
console.log(fooBar.ab);
fooBar.displayOptions();
The getters as a prototype using the this keyword in their return are the problem.
If I use Object.defineProperty the this keyword is wrong, unless I do it inside the constructor, but it would recreate the property on each instance of the class and slow my code down even further.
This works (I just messed up the syntax in my previous attempt):
// Class
function FooBar (options) {
this.options = options;
}
//Prototype getters
Object.defineProperty(FooBar.prototype, 'a', {
get: function() {
return this.options.a;
}
});
Object.defineProperty(FooBar.prototype, 'b', {
get: function() {
return this.options.b;
}
});
Object.defineProperty(FooBar.prototype, 'ab', {
get: function() {
return this.options.a + this.options.b;
}
});
// Methods
FooBar.prototype.displayOptions = function() {
console.log(this.options);
};
// Code
var options = {
a:'foo',
b:'bar'
};
var fooBar = new FooBar (options);
console.log(fooBar.a);
console.log(fooBar.b);
console.log(fooBar.ab);
fooBar.displayOptions();
For those who are curious about the benefits of converting scripts like this to run faster: Run following code and look to your output in the console (Chrome - 66% faster, Firefox - no difference (curious, since I got the warning from Firefox)):
// WITHOUT PROTOTYPING
var Person1 = function() {
this.name = 'myName';
this.changeName = function(name) {
this.name = name;
};
this.changeName2 = function(name) {
this.name = name;
};
this.changeName3 = function(name) {
this.name = name;
};
this.changeName4 = function(name) {
this.name = name;
};
}
// WITH PROTOTYPING, WITH MUTATION
var Person2 = function() {
this.name = 'myName';
}
Person2.prototype = {
changeName: function(name) {
this.name = name;
},
changeName2: function(name) {
this.name = name;
},
changeName3: function(name) {
this.name = name;
},
changeName4: function(name) {
this.name = name;
}
};
// WITH PROTOTYPING, WITHOUT MUTATION
var Person3 = function() {
this.name = 'myName';
}
Person3.prototype.changeName = function(name) {
this.name = name;
};
Person3.prototype.changeName2 = function(name) {
this.name = name;
};
Person3.prototype.changeName3 = function(name) {
this.name = name;
};
Person3.prototype.changeName4 = function(name) {
this.name = name;
};
// DO THE TEST
var i=0, len=1000000;
// TEST1
window.performance.mark('mark_test_start');
for(i=0;i<len;i++) {
p = new Person1();
p.changeName('myName2');
}
window.performance.mark('mark_test_end');
window.performance.measure('no-prototyping', 'mark_test_start', 'mark_test_end');
// TEST2
window.performance.mark('mark_test2_start');
for(i=0;i<len;i++) {
p = new Person2();
p.changeName('myName2');
}
window.performance.mark('mark_test2_end');
window.performance.measure('prototyping-with-mutation', 'mark_test2_start', 'mark_test2_end');
// TEST3
window.performance.mark('mark_test3_start');
for(i=0;i<len;i++) {
p = new Person2();
p.changeName('myName2');
}
window.performance.mark('mark_test3_end');
window.performance.measure('prototyping-without-mutation', 'mark_test3_start', 'mark_test3_end');
// OUTPUT tests
var items = window.performance.getEntriesByType('measure');
for (var i = 0; i < items.length; ++i) {
var req = items[i];
console.log(req.name + ': ' + req.duration.toFixed(2));
}

Using private members and methods in javascript

var test = function(id, company){
//public members
this.id = id;
this.company = company;
//private member
var age = 24;
//private method
var getAge = function(){
return this.age;
};
//public method
this.displayAge = function(){
console.log(getAge());
}
}
//invoking
var t = new test(1, 'XYZ Corp');
t.displayAge(); //undefined
Why is it not getting displayed
It's not being displayed because this.age is undefined. You want age.
Because of the scope of variables in js
A variable is visible inside a function not outside
var a = "foo"
function fooBar () {
var b = "bar"
console.log(a) // foo
console.log(b) // bar
}
console.log(a) // foo
console.log(b) // undefined
You want this:
var test = function(id, company){
//public members
this.id = id;
this.company = company;
//private member
var age = 24;
//private method
this.getAge = function(){
return age;
};
//public method
this.displayAge = function(){
console.log(this.getAge());
}
}
//invoking
var t = new test(1, 'XYZ Corp');
t.displayAge(); //undefined
Note that both "getAge" and "displayAge" need to be attached to this but your private variable "age" should not be.

In OPP JS can you access a method declared inside a prototype function from the constructor?

I'm reading about OPP js and while going over an example and was wondering if in:
function Person(name){
this.name = name;
}
Person.prototype.sayName = function(){
var tempName = this.name;
var saySomething = function(){
console.log(tempName);
}
//return saySomething();
}
var person1 = new Person('chris');
is theres a way to fire the saySomething method from the constructor.
eg.
person1.sayName().saySomething() //which doesnt work obviously
Returning an object when sayName will work:
function Person(name) {
this.name = name;
}
Person.prototype.sayName = function() {
var tempName = this.name;
return {
saySomething: function() {
console.log(tempName);
}
};
};
var person1 = new Person('chris');
person1.sayName().saySomething(); // logs 'chris'

How do I create a class in javascript

I need a student class in javascript with 2 data members Name and Age and 2 method get_record() and set_record(name,age). How do I do it in javascript and create multiple object of that class.
var Student = function(age, name){
this.age = age;
this.name = name;
this.get_age = function(){
return this.age;
}
this.get_name = function(){
return this.name;
}
this.set_age = function(age){
this.age = age;
}
this.set_name = function(name){
this.name = name;
}
}
var student = new Student(20,"XYZ");
You can model classes with new JavaScript based languages. Dart and TypeScript are probably the most popular in this respect.
This example is based on the JavaScript output from a TypeScript class.
var Student = (function() {
function Student(name, age) {
this.name = name;
this.age = age;
}
Student.prototype.get_record = function() {
return "Name: " + this.name + "\nAge: " + this.age;
}
Student.prototype.set_record = function(name, age) {
this.name = name;
this.age = age;
}
return Student;
})();
// Usage
var a = new Student("John", 23);
var b = new Student("Joe", 12);
var c = new Student("Joan", 44);
function student (age,name) {
this.name = name;
this.age = age;
this.get_record = function() {
return "name:"+this.name+" , age:"+this.age;
}
this.set_record = function(_name,_age) {
this.name=_name;
this.age=_age;
}
}
You can use 'constructor function'.
function Student() {
this.get_record = function(){ return this.name; };
this.set_record = function(name, age) {
this.name = name;
this.age = age;
};
return this;
}
var student1 = new Student();
var student2 = new Student();
student1.set_record('Mike', 30);
student2.set_record('Jane', 30);
student1.get_record();
student2.get_record();
More complex class structures are constructed via prototypes

javascript private variable through inheritance

I'm stuck with a problem using javascript...
I want to declare a private variable in a class that can't be used from its sublclass...what I've tried is:
function Person(){
var _name
this.setName = function(name){
_name = name
}
this.getName = function(){
return _name
}
}
function GreetingPerson(){
var self = this;
self.sayHello = function(){
console.log(self.getName() + ': "Hello!"');
}
}
GreetingPerson.prototype = new Person()
GreetingPerson.prototype.contructor = GreetingPerson;
var manuel = new GreetingPerson()
manuel.setName('Manuel');
manuel.sayHello();
var world = new GreetingPerson()
world.setName('World');
world.sayHello();
manuel.sayHello();
console.log(manuel.name)
In this way the name variable is private, but it is also static, so the last wo sayHello method calls, will write the same output.
I've tried also changing the Person class in this way:
function Person(){
this.setName = function(name){
this.name = name
}
this.getName = function(){
return this.name
}
}
But in this way it is not longer private.
What is the correct way to achieve it?
EDIT: Using something like #teddybeard says, you can get it too:
function Person(){
var _name;
this.setName = function(name){
_name = name;
};
this.getName = function(){
return _name;
};
return this;
}
function GreetingPerson(){
Person.call(this);
this.sayHello = function(){
console.log(this.getName() + ': "Hello!"');
};
return this;
}
GreetingPerson.prototype = new Person();
GreetingPerson.prototype.constructor = GreetingPerson;
var manuel = new GreetingPerson();
manuel.setName('Manuel');
manuel.sayHello();
var world = new GreetingPerson();
world.setName('World');
world.sayHello();
manuel.sayHello();
console.log(manuel._name);
But I'm not pretty sure if this is actually ok. The problem is that if you don't do something like Person.call(this); inside the constructor of GreetingPerson, you will not create a new instance of Person and it will always use the same _name value.
Check out Eloquent Javascript if you have time. I think this code should work for your purposes of inheritance.
function Person() {
var _name
this.setName = function(name) {
_name = name
}
this.getName = function() {
return _name
}
}
function GreetingPerson() {
Person.call(this);
this.sayHello = function() {
console.log(this.getName() + ': "Hello!"');
}
}
// taken from Eloquent Javascript
function clone(object) {
function OneShotConstructor() {}
OneShotConstructor.prototype = object;
return new OneShotConstructor();
}
GreetingPerson.prototype = clone(Person.prototype);
GreetingPerson.prototype.contructor = GreetingPerson;
var manuel = new GreetingPerson()
manuel.setName('Manuel');
manuel.sayHello();
var world = new GreetingPerson()
world.setName('World');
world.sayHello();
manuel.sayHello();
console.log(manuel.name)​;​

Categories