Object oriented JS - javascript

Why it doesn't work? When I'm trying to call example.example() I'm getting TypeError: example.example is not a function.
var example = class {
constructor(){
this.example = false;
}
id(){
this.example = !this.example;
return this.example;
}
};

When I'm trying to call example.example() I'm getting TypeError:
example.example is not a function.
example is a reference to an anonymous class, and its constructor can only be invoked with new
You need to call it as
var a = new example();
a.example; //false
Demo
var example = class {
constructor() {
this.example = false;
}
id() {
this.example = !this.example;
return this.example;
}
};
var a = new example()
console.log(a.example);

You have created class so you need to make an object of this.It should work by calling like this.
var example = class {
constructor(){
this.example = false;
}
id(){
this.example = !this.example;
return this.example;
}
};
console.log((new example()).id());
var obj = new example();
console.log(obj.id());

Related

Calling class instance as a function in JavaScript

Assuming I have a class
class foo {
constructor() {
this._pos = 0;
}
bar(arg) {
console.log(arg);
}
}
const obj = new foo();
How do I make it possible to call:
let var1 = obj('something');
You can make a callable object by extending the Function constructor, though if you want it to access the instance created, you'll actually need to create a bound function in the constructor that binds the instance to a function that is returned.
class foo extends Function {
constructor() {
super("...args", "return this.bar(...args)");
this._pos = 0;
return this.bind(this);
}
bar(arg) {
console.log(arg + this._pos);
}
}
const obj = new foo();
let var1 = obj('something ');

How to control if an object should not be created in Javascript

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);

Call parent method in JavaScript class but stll have access to prototype methods inside object instance?

Is it possible to call parent method in JavaScript class but to still have access to prototype methods from parent and child class. Here is code example:
var Base = function() {
this.baseMethod = function(){
return 'baseMethod';
};
this.baseInitMethod = function() {
return 'baseInitMethod';
}
}
Base.prototype.basePrototypeMethod = function() {
return "basePrototypeMethod";
};
var Specific = function() {
Base.call(this);
this.baseInitMethod = function() {
// call baseInitMethod from Base class
}
this.specificMethod = function(){
return 'specificMethod';
}
this.specificInitMethod = function() {
return this.basePrototypeMethod();
}
}
Specific.prototype.specificPrototypeMethod = function() {
return 'specificPrototypeMethod' + '-' + this.baseInitMethod();
}
for(var p in Base.prototype) {
Specific.prototype[p] = Base.prototype[p]
}
var s = new Specific();
console.log(s.baseMethod());
console.log(s.baseInitMethod());
console.log(s.basePrototypeMethod());
console.log(s.specificMethod());
console.log(s.specificInitMethod());
console.log(s.specificPrototypeMethod());
I want to call baseInitMethod in Base class from baseInitMethod method inside Specific class but so that all function calls from above still works. Is that possible?
Your Specific.prototype object should inherit from the Base.prototype object. Currently you're copying over all its properties to the object with this code:
for(var p in Base.prototype) {
Specific.prototype[p] = Base.prototype[p]
}
But you should actually use Object.create to establish a real prototype chain:
Specific.prototype = Object.create(Base.prototype);
Specific.prototype.specificPrototypeMethod = function() {
return 'specificPrototypeMethod' + '-' + this.baseInitMethod();
}
I want to call baseInitMethod in Base class from baseInitMethod method inside Specific class
Yes. In your Specific constructor, you first need get Base's baseInitMethod instance method, before you overwrite the property of the instance:
function Specific() {
Base.call(this);
var parentInitMethod = this.baseInitMethod;
this.baseInitMethod = function() {
// call baseInitMethod from Base class:
parentInitMethod.call(this /*, arguments…*/);
}
…
}
so that all function calls from above still works.
I'm not sure what you mean by that exactly. The specificPrototypeMethod will always call the baseInitMethod of the current instance, which would be Specific's overwritten one not the original that was defined in Base.
Here is what you need to do:
var Base = function () {
};
Base.prototype.baseMethod = function () {
return 'baseMethod';
};
Base.prototype.baseInitMethod = function () {
return 'baseInitMethod';
};
Base.prototype.basePrototypeMethod = function () {
return "basePrototypeMethod";
};
var Specific = function () {
Base.apply(this, arguments);
};
Specific.prototype.baseInitMethod = function () {
Base.prototype.baseInitMethod.apply(this,arguments);
};
Specific.prototype.specificMethod = function () {
return 'specificMethod';
};
Specific.prototype.specificInitMethod = function () {
var basePrototypeMethodCallResult = Base.prototype.basePrototypeMethod.apply(this,arguments);
};
You're overwriting the baseInitMethod of Base inside Specific, with Specific's definition, so why would you ever want to call the Base version? If you simply remove the overwrite of the function you should call the Base definition:
var Base = function() {
this.baseMethod = function(){
return 'baseMethod';
};
this.baseInitMethod = function() {
return 'baseInitMethod';
}
}
Base.prototype.basePrototypeMethod = function() {
return "basePrototypeMethod";
};
var Specific = function() {
Base.call(this);
this.baseInitMethod(); // calls the Base definition only
this.specificMethod = function(){
return 'specificMethod';
}
this.specificInitMethod = function() {
return this.basePrototypeMethod();
}
}
One might argue "Why always trying to mimic 'classical' behaviour and fuss with call and apply instead of embracing the prototype delegation pattern instead?"
Here is what I would code :
var Base = {
baseVariable1: "baseValue1",
baseVariable2: "baseValue2",
baseMethod: function () {
return 'baseMethod';
},
baseInitMethod: function () {
return 'baseInitMethod';
}
}
var Specific = Object.create(Base);
Specific.variable1 = "value1";
Specific.variable2 = "value2";
Specific.specificInitMethod = function () {
return 'specificInitMethod' + '-' + this.baseInitMethod();
}
Specific.specificMethod = function () {
return 'specificMethod' + '-' + this.baseInitMethod();
}
var s = Object.create(Specific);
console.log(s.baseInitMethod());
console.log(s.baseVariable1);
console.log(s.baseVariable2);
console.log(s.variable1);
console.log(s.variable2);
console.log(s.baseMethod());
console.log(s.specificInitMethod());
console.log(s.specificMethod());
class Parentable {
get parent() {
return this.__proto__.__proto__;
}
}
class A extends Parentable {
say() {
console.log('Hello from A');
}
}
class B extends A {
say() {
console.log('Im not A, I am B! But A send you a message:');
this.parent.say();
}
}
(new B()).say();

Class Function Call

I have a class setup as follows:
var oTest = new TEST();
function TEST() {
this.String = function(sString) {
this.Trim = function() {
}
}
}
I want to be able to call the Trim function as follows:
var sTrimmed = oTest.String(" something").Trim();
Is this the correct approach? Any help would be greatly appreciated as i have never done functions inside class functions before.
Add your methods to the prototype of the constructor function, and do return this; in String, to return the same object, which makes it chainable.
var oTest = new TEST();
function TEST() {}
TEST.prototype.String = function(aString) {
this.the_string = aString;
return this;
};
TEST.prototype.Trim = function() {
this.the_string = this.the_string.trim();
return this;
};
TEST.prototype.getString = function() {
return this.the_string;
};
var sTrimmed = oTest.String(" something")
.Trim()
.getString();
live demo: http://jsfiddle.net/BcwgC/

Calling method using JavaScript prototype

Is it possible to call the base method from a prototype method in JavaScript if it's been overridden?
MyClass = function(name){
this.name = name;
this.do = function() {
//do somthing
}
};
MyClass.prototype.do = function() {
if (this.name === 'something') {
//do something new
} else {
//CALL BASE METHOD
}
};
I did not understand what exactly you're trying to do, but normally implementing object-specific behaviour is done along these lines:
function MyClass(name) {
this.name = name;
}
MyClass.prototype.doStuff = function() {
// generic behaviour
}
var myObj = new MyClass('foo');
var myObjSpecial = new MyClass('bar');
myObjSpecial.doStuff = function() {
// do specialised stuff
// how to call the generic implementation:
MyClass.prototype.doStuff.call(this /*, args...*/);
}
Well one way to do it would be saving the base method and then calling it from the overriden method, like so
MyClass.prototype._do_base = MyClass.prototype.do;
MyClass.prototype.do = function(){
if (this.name === 'something'){
//do something new
}else{
return this._do_base();
}
};
I'm afraid your example does not work the way you think. This part:
this.do = function(){ /*do something*/ };
overwrites the definition of
MyClass.prototype.do = function(){ /*do something else*/ };
Since the newly created object already has a "do" property, it does not look up the prototypal chain.
The classical form of inheritance in Javascript is awkard, and hard to grasp. I would suggest using Douglas Crockfords simple inheritance pattern instead. Like this:
function my_class(name) {
return {
name: name,
do: function () { /* do something */ }
};
}
function my_child(name) {
var me = my_class(name);
var base_do = me.do;
me.do = function () {
if (this.name === 'something'){
//do something new
} else {
base_do.call(me);
}
}
return me;
}
var o = my_child("something");
o.do(); // does something new
var u = my_child("something else");
u.do(); // uses base function
In my opinion a much clearer way of handling objects, constructors and inheritance in javascript. You can read more in Crockfords Javascript: The good parts.
I know this post is from 4 years ago, but because of my C# background I was looking for a way to call the base class without having to specify the class name but rather obtain it by a property on the subclass. So my only change to Christoph's answer would be
From this:
MyClass.prototype.doStuff.call(this /*, args...*/);
To this:
this.constructor.prototype.doStuff.call(this /*, args...*/);
if you define a function like this (using OOP)
function Person(){};
Person.prototype.say = function(message){
console.log(message);
}
there is two ways to call a prototype function: 1) make an instance and call the object function:
var person = new Person();
person.say('hello!');
and the other way is... 2) is calling the function directly from the prototype:
Person.prototype.say('hello there!');
This solution uses Object.getPrototypeOf
TestA is super that has getName
TestB is a child that overrides getName but, also has
getBothNames that calls the super version of getName as well as the child version
function TestA() {
this.count = 1;
}
TestA.prototype.constructor = TestA;
TestA.prototype.getName = function ta_gn() {
this.count = 2;
return ' TestA.prototype.getName is called **';
};
function TestB() {
this.idx = 30;
this.count = 10;
}
TestB.prototype = new TestA();
TestB.prototype.constructor = TestB;
TestB.prototype.getName = function tb_gn() {
return ' TestB.prototype.getName is called ** ';
};
TestB.prototype.getBothNames = function tb_gbn() {
return Object.getPrototypeOf(TestB.prototype).getName.call(this) + this.getName() + ' this object is : ' + JSON.stringify(this);
};
var tb = new TestB();
console.log(tb.getBothNames());
function NewClass() {
var self = this;
BaseClass.call(self); // Set base class
var baseModify = self.modify; // Get base function
self.modify = function () {
// Override code here
baseModify();
};
}
An alternative :
// shape
var shape = function(type){
this.type = type;
}
shape.prototype.display = function(){
console.log(this.type);
}
// circle
var circle = new shape('circle');
// override
circle.display = function(a,b){
// call implementation of the super class
this.__proto__.display.apply(this,arguments);
}
If I understand correctly, you want Base functionality to always be performed, while a piece of it should be left to implementations.
You might get helped by the 'template method' design pattern.
Base = function() {}
Base.prototype.do = function() {
// .. prologue code
this.impldo();
// epilogue code
}
// note: no impldo implementation for Base!
derived = new Base();
derived.impldo = function() { /* do derived things here safely */ }
If you know your super class by name, you can do something like this:
function Base() {
}
Base.prototype.foo = function() {
console.log('called foo in Base');
}
function Sub() {
}
Sub.prototype = new Base();
Sub.prototype.foo = function() {
console.log('called foo in Sub');
Base.prototype.foo.call(this);
}
var base = new Base();
base.foo();
var sub = new Sub();
sub.foo();
This will print
called foo in Base
called foo in Sub
called foo in Base
as expected.
Another way with ES5 is to explicitely traverse the prototype chain using Object.getPrototypeOf(this)
const speaker = {
speak: () => console.log('the speaker has spoken')
}
const announcingSpeaker = Object.create(speaker, {
speak: {
value: function() {
console.log('Attention please!')
Object.getPrototypeOf(this).speak()
}
}
})
announcingSpeaker.speak()
No, you would need to give the do function in the constructor and the do function in the prototype different names.
In addition, if you want to override all instances and not just that one special instance, this one might help.
function MyClass() {}
MyClass.prototype.myMethod = function() {
alert( "doing original");
};
MyClass.prototype.myMethod_original = MyClass.prototype.myMethod;
MyClass.prototype.myMethod = function() {
MyClass.prototype.myMethod_original.call( this );
alert( "doing override");
};
myObj = new MyClass();
myObj.myMethod();
result:
doing original
doing override
function MyClass() {}
MyClass.prototype.myMethod = function() {
alert( "doing original");
};
MyClass.prototype.myMethod_original = MyClass.prototype.myMethod;
MyClass.prototype.myMethod = function() {
MyClass.prototype.myMethod_original.call( this );
alert( "doing override");
};
myObj = new MyClass();
myObj.myMethod();

Categories

Resources