Adding a property to a "Class" in JavaScript - javascript

There are no actual classes in javascript. But you have to work with what you get.
Lets take this example "Class":
var example = function (string) {
this._self = string;
}
With the above, you could do something like:
var ex = new example("Hello People."),
display = ex._self; // returns "Hello People."
I thought that by using something like example.prototype.newFun = function(){} would add a new property to that "Class". But it isn't working in my code.
Here is the full code i'm testing:
var example = function (string) {
this._self = string;//public, var like, storage
}
var showExample = new example("Hello People");
showExample.prototype.display = function (a) {//code stops here, with error "Uncaught TypeError: Cannot set property 'display' of undefined"
return a;
}
console.log(showExample._self);
console.log(showExample.display("Bye"));
What i'm trying to do is add the display function to the example function as a "public function". I might be doing something wrong.

It's not the object that has the prototype, it's the function that you use to create the object:
var example = function (string) {
this._self = string;
}
example.prototype.display = function (a) {
return a;
};

Because there's no prototype for showExample - it's only an instance of example. Try to do this: example.prototype.display = function (a) {} and it will work.
Here's a bit more on classes in JavaScript:
3 Ways to "define" classes
This lovely SO question
I like the way Classy handles this and also how classes are implemented in CoffeeScript.

You can modify to the constructor of showExample ..
ex.
showExample.constructor.prototype.display = function (a) {
return a;
}

You try to add a method to the prototype of the instance of example (showExample). The instance has no prototype. Try example.prototype.display = function() {/*...*/}; (in other words, add the method to the prototype of the constructor of showExample, that is example) and check again. After that, all instances of example 'know' the display method, or in your words, display is 'public' to all instances.
You can add the method to the instance using showExample.display = function() {/*...*/};. Using that, only showExample knows the the display method.

in your case showExample is an object of example...
use
example.prototype.display = function(a)...

Related

Using var to refer to a constructor in javascript [duplicate]

I would like to get an object from its name in Javascript.
I'm working on an application which will need to load up some different context, I'm trying so to load different classes with the "inherit" jquery plugin. Everything works just fine, excepts that, when I need to instanciate a class I can't because I've only the name of the class and not the object directly.
Basically, I would like to find something like 'getClass(String name)'. Does anyone could help me ?
Don't use eval().
You could store your classes in a map:
var classes = {
A: <object here>,
B: <object here>,
...
};
and then just look them up:
new classes[name]()
JavaScript: Call Function based on String:
function foo() { }
this["foo"]();
You can perfectly use eval() without a security risk:
var _cls_ = {}; // serves as a cache, speed up later lookups
function getClass(name){
if (!_cls_[name]) {
// cache is not ready, fill it up
if (name.match(/^[a-zA-Z0-9_]+$/)) {
// proceed only if the name is a single word string
_cls_[name] = eval(name);
} else {
// arbitrary code is detected
throw new Error("Who let the dogs out?");
}
}
return _cls_[name];
}
// Usage
var x = new getClass('Hello')() // throws exception if no 'Hello' class can be found
Pros: You don't have to manually manage a map object.
Cons: None. With a proper regex, no one can run arbitrary code.
Do you mean this?
function Person(name){
this.name = name;
}
function getClass(str_name, args){
return new (window[str_name])(args);
}
var wong2 = getClass("Person", "wong2");
alert(wong2.name); // wong2

Why can’t I access a property on “this” in a class via its prototype?

I wrote this class and have set up an array property for it. Then, I want to add an item to this array.
However, when I try to do it, I get the error “Uncaught TypeError: Cannot read property push of undefined”.
Isn’t this possible?
class test {
constructor() {
this.myArray = [];
}
myMethod() {
this.myArray.push("ok");
}
};
console.log(test.prototype.myMethod());
That’s not how classes are used. You need to instantiate test first, by using new test(). The constructor was never called in your case, so this.myArray was never defined.
This is the only way this can work:
let testInstance = new test();
testInstance.myMethod();
This way, the constructor is called and there will be no error.
Of course, next you’ll need some way of retrieving your array, in order to see the effect.
try to create the instance first. See the code I've commented it in details
test.prototype = {
constructor: test,
myMethod: function() {
this.myArray.push("ok");
}
};
var test = function(){
this.myArray = [];
}
test.prototype = { // add our custom constructor and custom methods
constructor: test,
myMethod: function() {
this.myArray.push("ok");
}
};
var myVar = new test(); // create new instance of test
myVar.myMethod(); // run custom method to push val
console.log( myVar.myArray );
You need to initiate your class test first.
var t = new test();
For your information:
console.log(test.prototype.myMethod());
will give you "undefined". Try e.g. :
var t = new test();
t.myMethod();
console.log(t.myArray);
to get output similar to this:
Array [ "ok" ]

Get object class from string name in javascript

I would like to get an object from its name in Javascript.
I'm working on an application which will need to load up some different context, I'm trying so to load different classes with the "inherit" jquery plugin. Everything works just fine, excepts that, when I need to instanciate a class I can't because I've only the name of the class and not the object directly.
Basically, I would like to find something like 'getClass(String name)'. Does anyone could help me ?
Don't use eval().
You could store your classes in a map:
var classes = {
A: <object here>,
B: <object here>,
...
};
and then just look them up:
new classes[name]()
JavaScript: Call Function based on String:
function foo() { }
this["foo"]();
You can perfectly use eval() without a security risk:
var _cls_ = {}; // serves as a cache, speed up later lookups
function getClass(name){
if (!_cls_[name]) {
// cache is not ready, fill it up
if (name.match(/^[a-zA-Z0-9_]+$/)) {
// proceed only if the name is a single word string
_cls_[name] = eval(name);
} else {
// arbitrary code is detected
throw new Error("Who let the dogs out?");
}
}
return _cls_[name];
}
// Usage
var x = new getClass('Hello')() // throws exception if no 'Hello' class can be found
Pros: You don't have to manually manage a map object.
Cons: None. With a proper regex, no one can run arbitrary code.
Do you mean this?
function Person(name){
this.name = name;
}
function getClass(str_name, args){
return new (window[str_name])(args);
}
var wong2 = getClass("Person", "wong2");
alert(wong2.name); // wong2

Javascript object that inherits QWidget

I am doing something in Javascript and Qt, and for my purpose, I need a javascript object that inherits QWidget. So far, I have tried the following:
function Test()
{
QWidget.call(this);
this.button = new QPushButton("test");
this.layout().insertWidget(1,this.button);
this.button.clicked.connect(this.slot);
}
Test.prototype.slot = function()
{
print("Test button clicked");
}
Test.prototype = new QWidget();
I instantiate object from the class "Test" and with the call of the show() method, I get the widget:
var testVariable = new Test();
testVariable.show();
However, I get the following interpreter error:
Error: In run/evaluate: TypeError:
Function.prototype.connect: target is
not a function
If I change the line this.button.clicked.connect(this.slot); to call a static method defined like this:
this.button.clicked.connect(Test.slot);
...
...
Test.slot = function () { /* code */ }
the program runs fine, but static method is a no-no. I don't want anyone to call slot() except the instantiated object.
What is wrong with this picture? Has anyone had experience with Javascript objects inheriting Qt objects?
Thanks in advance
Ok I think I might figured this out. So the magic here is:
Test.prototype = new QWidget();
needs to be before the constructor, also the constructor has to take "parent" argument too. And last but not least, in connect() there are two arguments: first is which class contains the slot (in my case it is this) and the name of the slot with this pointer.
So, having this in mind, the above code will look like this:
Test.prototype = new QWidget();
function Test(parent)
{
QWidget.call(this, parent);
this.button = new QPushButton("test");
this.layout().insertWidget(1, this.button);
this.button.clicked.connect(this, this.slot);
}
Test.prototype.slot = function()
{
print("Test button clicked");
}
This is to whom it may concern.

Getting object name within the objectscope

I have a Javascript class that contains
add
remove
removeall
update
.
.
.
updateLik
.
.
functions.
And in my Serverside script a have Links like
Add
Now if user click on the DIV, the function "add" will be called.
and the add function calls in turn the updateLink function.
updateLink replaces the onclick attribute to "myobject.delete(100)"
Now my problem is that in updateLink function i had to hardcode the objectname
to call its delete function.
Is there any way to get the objectname, or any other solution?
Thanks
You could store a reference of the context where your object is created, and then search within it, looking for the actual instance:
function MyClass() {
this.getVarName = function () {
for (var name in this.scope)
if (this.scope[name] === this)
return name;
}
}
MyClass.prototype.scope = this;
var myObject = new MyClass();
myObject.getVarName(); // returns "myObject"
Simplest way is to use eval.
var myObject = eval(myObjectName);
That is if you have the name of the object in a string format.
I would also look at at the YUI event library. It allows you to execute any function in any scope.
http://developer.yahoo.com/yui/event/
Example:
var x = new YourClass();
var y = x;
Question: What is the name of your object? x or y?
Solution:
var x = new YourClass('x'); // and have your class copy the name
or
var x = new YourClass();
x.name = 'x';
delete is a keyword so you cannot use it with dot-notation (object.method). You have to use ['property']-notation (object['method']).
var obj = {delete: function(){}}; // throws a syntax error
var obj = {'delete': function(){}}; // works
obj.delete() // throws a syntax error
obj['delete']() // works

Categories

Resources