I have a class with a method
function MyClass(name){
this._name = name;
}
MyClass.prototype.test=function(){
console.log(this._name);
}
This work if create new instance
var a = new MyClass('demo');
a.test();
But, now I want call this class like a function without create instance
MyClass('demo2').test();
Is this possible?
You can check if this is an instance of the class, if the check is false it means that it is called as a function and you can return a new instance:
function MyClass(name){
if (!(this instanceof MyClass)) {
return new MyClass(name);
}
this._name = name;
}
in this way you can get a new instance of the class with or without the new keyword.
Yes it is possible. You can return a custom object with necessary properties.
function MyClass(name){
// private variable
var _name = name;
var getName = function(){
return _name;
};
// public properties
return {
test: getName
}
}
console.log(MyClass('Foo').test())
console.log(MyClass('Foo')._name)
or you can have inner private class which is only available inside MyClass.
function MyClass(name){
function Person(){
this._name = name;
}
Person.prototype.getName = function(){
return this._name
}
return new Person()
}
console.log(MyClass('Foo').getName())
console.log(MyClass('Foo')._name)
Related
var Person = (function () {
var name = Symbol('name');
class Person {
constructor(name) {
this[name] = name
}
getname() {
return this[name];
}
}
}());
var person = new Person();
console.log(person.getname())
I'm making a small example via a tutorial on Google. This example prevents to access property this.name from outside scope. But I'm getting error
Uncaught TypeError: Person is not a constructor.
How can I solve it?
You have to return Person class and use another variable name for storing symbol since it's the same as constructor argument name:
var Person = (function () {
var nameSymbol = Symbol('name');
return class Person {
constructor(name) {
this[nameSymbol] = name;
}
getname() {
return this[nameSymbol];
}
}
}());
var person = new Person('John');
console.log(person.getname())
function Person (name) {
this.name = name;
this.getname=function() {
return this[name];
};
}
var person = new Person('name');
console.log(person.getname())
You don't have to enclose class within a function. ES5 needs functions to create a class. The code snippet you have provides makes a mix of ES5 and ES6. Simple use as below:
class Person {
constructor(name) {
this.name = name
}
getname() {
//return this.name;
return this['name'];
}
}
let person = new Person('Alex');
console.log(person.getname());
If you are using [] notation to access object properties then remember that it must be a string i.e.wrapped in quotes
What am I trying to do is as following:
var Person = function(name) {
this.name = name;
}
Person.prototype.getName = function () {
return this.name;
}
// This will return error;
console.log(Person('John').getName());
// While this won't.
var p1 = new Person('john');
console.log(p1.getName());
Am I misunderstanding something?
// This will return error;
console.log(Person('John').getName());
it returns an error bcoz Person() by default returns undefined ,but if you use new it will return the newly created object.
// While this won't.
var p1 = new Person('john');
console.log(p1.getName());
this works bcoz a new object with __proto__ set to Person.prototype is returned and since there is a getName() on it , it works as expected.
you may use scope safe constructor for your constructor to work without explicit new.
function Person(name) {
if(this instanceof Person) {
this.name = name;
} else {
return new Person(name);
}
}
http://www.mikepackdev.com/blog_posts/9-new-scope-safe-constructors-in-oo-javascript
If you don't want to have the new keyword all over your code (and I can't think of a good reason to want that, you would be basically hiding an important information), you could just do something like:
var pPerson = function(name) {
this.name = name;
};
pPerson.prototype.getName = function () {
return this.name;
};
var Person = function (name) {
return new pPerson(name);
};
You can use Object.create() if you don't want to use the new keyword. Here's an example from MDN:
// Animal properties and method encapsulation
var Animal = {
type: "Invertebrates", // Default value of properties
displayType : function(){ // Method which will display type of Animal
console.log(this.type);
}
}
// Create new animal type called animal1
var animal1 = Object.create(Animal);
animal1.displayType(); // Output:Invertebrates
// Create new animal type called Fishes
var fish = Object.create(Animal);
fish.type = "Fishes";
fish.displayType(); // Output:Fishes
If you really really hate your self, you can do this
var Person = function(name) {
var This = {};
This.name = name;
//See note
Object.setPrototypeOf(This, arguments.callee.prototype);
return This;
}
Person.prototype.getName = function () {
return this.name;
}
var p = Person('John');
console.log(p.getName());
Note
You absolutely have to read about this.
You can try creating prototype functions as a part of parent function itself.
var Person = function(name) {
this.name = name;
this.get_name = function() {
return this.name;
}
return this;
}
Person.prototype.getName = function() {
return this.name;
}
// This will return error;
console.log(Person('John').get_name());
// While this won't.
var p1 = new Person('john');
console.log(p1.getName());
function Mammal(name){
this.name = name;
}
Mammal.prototype.displayName = function(){
return this.name;
}
function Organism(name){
this.orgName = name;
}
Organism.prototype.print = function(){
return this.orgName;
}
Organism.prototype = new Mammal(); //Organism inherits Mammal
//Testing
var o = new Organism('Human');
o.print()
This comes as undefined. Why? this should show since it is a method of class Organism.
print() does not show up in the object
When you do:
Organism.prototype = new Mammal(); //Organism inherits Mammal
you replace the entire prototype object, thus wiping out the previously assigned:
Organism.prototype.print = function(){
return this.orgName;
}
You can fix it by changing the order so you "add" your new method to the inherited prototype:
function Organism(name){
this.orgName = name;
}
Organism.prototype = new Mammal(); //Organism inherits Mammal
Organism.prototype.print = function(){
return this.orgName;
}
FYI as an aside, you should be thinking about using Organism.prototype = Object.create(Mammal.prototype); instead and you should be calling the constructor of the base object too. See here on MDN for examples.
When you assign
Organism.prototype = new Mammal();
you are clobbering the Organism.prototype object that had the print function on it. Try this instead for your inheritance:
function Mammal(name){
this.name = name;
}
Mammal.prototype.displayName = function(){
return this.name;
}
function Organism(name){
this.orgName = name;
}
Organism.prototype = Object.create(Mammal.prototype);
Organism.constructor = Mammal;
// or _.extend(), if using underscore
jQuery.extend(Organism.prototype, {
print: function(){
return this.orgName;
}
});
//Testing
var o = new Organism('Human');
o.print()
I had written this code to simulate OOP inheritance and calling baseclass in javascript and it works:
function Animal(name,age)
{
this._name = name;
this.setName = function (name) { this._name = name }
this.getName = function() { return this._name }
}
function Cat(name,age)
{
Animal.call(this,name,age); // call baseclass constructor
this.getName = function() { return Cat.prototype.getName.call(this)+", a cat" }
}
Cat.prototype = new Animal(); // will create the baseclass structure
/// ***** actual execution *****
var puss = new Cat("Puss",3);
var cheshire = new Cat("Cheshire",10);
// do some actions
console.log ( puss.getName() );
// change cat's name
puss.setName("Puss in boots");
alert ( "new name -->"+puss.getName() );
problem is that, for each instance of "new Cat()" the "getName" and "setName" functions are replicated.
I have read a lot of articles on prototyping but none addressed the issue of calling the baseclass function.
You should assign the methods to the prototype of the function, for example,
function Animal(name, age) {
this._name = name;
this._age = age;
}
Animal.prototype.getName = function () { return this._name; }
Animal.prototype.setName = function (value) { this._name = value; }
function Cat(name, age) {
Animal.call(this, name, age);
}
Cat.prototype = new Animal();
Cat.prototype.getName = function () {
return Animal.prototype.getName.call(this) + ", a cat";
}
Are you looking for __proto__ which stores prototype data?
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/Proto
If you do a console.log(puss.__proto__.getName) you'll get what seems to be the "baseclass" function but I'm not sure how cross-browser is this.
From http://phrogz.net/js/classes/OOPinJS2.html
Javascript does not have any sort of 'super' property, which would
point to its parent class. Instead, you use the call() method of a
Function object, which allows you to run a function using a different
object as context for it. If you needed to pass parameters to this
function, they would go after the 'this'.
In your case it works the same for functions as "methods", so you can do:
Animal.prototype.setName.call(this, name);
I have an object written like this:
Object1.prototype = {
isInit: false,
Get : function (){}
}
Now I'd like to add a constructor which takes one parameter. How can I do it?
Class declaration
var User = function(name, age) { // constructor
}
User.prototype = {}
Instance variables (members)
var User = function(name, age) {
this.name = name;
this.age = age;
}
User.prototype = {}
Static variables
var User = function(name, age) {
this.name = name;
this.age = age;
}
User.prototype = {
staticVar: 15,
anotherStaticVar: 'text'
}
Here I defined two static variables. Each User instance has access to these two variables. Note, that we can initialize it with value;
Instance functions (methods)
var User = function(name, age) {
this.name = name;
this.age = age;
}
User.prototype = {
getName: function() {
return this.name;
},
setName: function(name) {
this.name = name;
}
}
Usage example:
var user = new User('Mike', 29);
user.setName('John');
alert(user.getName()); //should be 'John'
Static functions
var User = function(name, age) {
this.name = name;
this.age = age;
}
User.create = function(name, age) {
return new User(name, age);
}
User.prototype = {}
Assuming that by "ctor" you mean "constructor", in JavaScript that's just a function. In this case your constructor would need to be "Object1" itself - in other words, what you've got there makes sense if you have already defined "Object1" to be a function.
Thus,
function Object1(param) {
// constructor code
}
would be the constructor for your type.
Now there are some JavaScript libraries that provide a utility layer for defining classes. With those, you generally pass some sort of object (like you've got) that includes an "init" function. The libraries provide APIs for creating "classes" and for extending one class from another.
Javascript has prototype based object model. Check this mozilla wiki page and suddenly you'll feel much better in js land.
We can define a constructor in javaScript is same as we fine function, so constructor is just a function.
//function declaration
function func(){}
In case of Contructor We use initial letter in caps in construct like
//constructor
function Func(){}
now do whatever you want to with your constructor
var constructor1 = new Func();
class CLASS_NAME
{
private:
int variable;
public:
CLASS_NAME() //constructor
{
variable = 0;
}
};