I have tried to create javascript object like
function Caller() {
this.init = function() {
makeCall();
};
this.makeCall = function(){/*come code here*/}
}
var a = new Caller();
a.init();
I got error function is not defined, same thing happens when I try to call this.makeCall();
When I remove this from makeCall definition it works, but when I remove also from init it doesn't work. How to solve this ?
Use this.makeCall(). Additionally define makeCall() before its use.
function Caller() {
this.makeCall = function () { /*come code here*/ }
this.init = function () {
this.makeCall();
};
}
var a = new Caller();
a.init();
DEMO
Use this.makeCall() it is a method so you can use it.
Try this this.makeCall() function is executed successfully here.
<html>
<head>
</head>
<body>
<script>
function Caller() {
this.init = function() {
this.makeCall();
};
this.makeCall = function(){
alert('hello');
}
}
var a = new Caller();
a.init();
</script>
</body>
</html>
You need to call the function properly using this
makeCall(); => this.makeCall();
You can use IIFE to declare Caller:
var Caller=(function () {
function constructor() {
}
function makeCall() {
/*come code here*/
}
constructor.prototype.init=function () {
makeCall.apply(this, arguments);
};
return constructor;
})();
var a=new Caller();
a.init();
and be sure that Caller is loaded before it is invoked.
To answer your question and to enhance your code you should have a look at this:
function Caller(){};
This is your constructor.
You can then add methods to your constructor like this:
Caller.prototype.init = function () {
// do something
}
When you create instances of your "class" Caller
var a = new Caller();
every instance will have the methods you described in the Caller.prototype object.
And to solve your problem:
If one prototype method wants to call another prototype method, you need to do this:
// do some setup in your constructor
function Caller(phoneNumber) {
this.phoneNumber = phoneNumber;
};
Caller.prototype.init = function () {
// the code word "this" will be the instance itself
this.makeCall();
};
Caller.prototype.makeCall = function () {
// do whatever this method needs to do
alert('calling ' + this.phoneNumber);
};
var a = new Caller(0123456789);
a.init();
The main thing to understand is, that in every prototype method, the keyword this references the current instance of the constructor (in this case Caller).
Related
I have the following code.
function Test() {
this.funct_1 = function() {
alert('funct_1');
}
this.funct_2 = function() {
alert('funct_2');
}
return this;}
function getTestObj() {
var testObj;
if (!testObj) {
testObj = new Test();
}
return function() {
return testObj;
}}
What I'm trying to accomplish is the following. I want to have a class Test which is not singleton. Then in some other places in my application I need to have a function which could return the same instance per script execution. I figured that I could use closure for that getTestObj.
However, when I try to use it
getTestObj().funct_1();
I'm getting the following error, saying the funct_1() is not found.
Cannot find function funct_1 in object function () {...}.
Clearly, I'm making some kind of mistake here, but I'm not able to find any solution over the net which could help me. Would appreciate any comments.
NOTE: I'm forced to use ECMA5
testObj is wrapped inside a function
So, either call it
getTestObj()().funct_1(); //notice two ()()
Save the value of getTestObj() in a variable
var singleTon = getTestObj();
var testObj = singleTon();
testObj.funct_1();
Or, simply return testObj (in case singleTon isn't required)
function getTestObj()
{
var testObj;
if (!testObj) {
testObj = new Test();
}
return testObj;
}
And invoke it as
getTestObj().funct_1(); //notice single ()
getTestObj() is returning a function i.e. :
function() {
return testObj;
}
So you have to call it again getTestObj()(), this will return the Test's object and now you can access it's properties.
getTestObj()().funct_1();
OR
You can change your getTestObj function as :
function getTestObj() {
var testObj;
if (!testObj) {
testObj = new Test();
}
return (function() {
return testObj;
}());
}
I have a context function type that is defined as below:
var Context = function () {
this.run = function () {
method1();
method2();
}
var method1 = function () {
}
}
As it is clear in the definition, method2 is not defined in the context. I need every instance of Context passes its implementation of this method.
var c = new Context();
// This does not work! because the call in run() function
// is not this.method2();
c.method2 = function () {
alert("injected method2");
};
c.run();
I need to keep method2() in run without use of this object i.e. this.method2();
Any solution?
If you can define method2 before creating Context it will work no problem:
function method2() {
alert(2);
}
var c = new Context();
c.run();
You can add method2 to the window object instead of the c object, in which case it will work.
Note that this is a clear indicator of poor design. You should probably look into doing this differently.
Callback approach:
var Context = function (callback) {
this.run = function () {
method1();
if(callback) callback();
}
var method1 = function () {
}
}
var c = new Context(function () {
alert("injected method2");
});
c.run();
If you change your run method to the following it should work as expected
this.run = function () {
method1();
this.method2();
}
UPDATE: I just realized it looks like you want to be able to do this on all instances of Context objects. In that case you would also need to define method2 on Context.prototype and not just on c
Context.prototype.method2 = function () {
console.log("injected method2dfd");
};
Is it possible to make a wrapper function MyFunction, which when called with new as in
instance = new MyFunction();
really returns the same object as if the callsite called SomeOtherFunction without new?
instance = SomeOtherFunction();
(I've looked at Proxy but doesn't look like they're supported in Chrome yet.)
Edit:
It turns out the callsite calls MyFunction like this:
var instance = Object.create(MyFunction.prototype);
MyFunction.apply(instance, [/* arguments */]);
// `instance` is supposed to be initialized here
I think this is what you are looking for? Note as Jan Dvorak mentioned, you can only return objects.
function SomeObject() {
return Construct();
}
function Construct() {
return { 'name' : 'yessirrreee' };
}
console.log(new SomeObject())
You can try something like this
function MyClass() {
}
var ob = new MyClass();
Edit after comments
I think this questions needs more context.
I suggest you read about higher order components, but until you've better clarified what exactly you're trying to accomplish, I cannot help you.
I really don't know what your code looks like, but here are some suggestions
either way. My guess nr2 is what you're looking for:
// 1
function MyFunction() {
this.__proto__ = SomeOtherFunction()
}
function SomeOtherFunction() {
return {
foo: function() {
return 'bar'
}
}
}
var fn = new MyFunction()
fn.foo()
// 2
function MyFunction() {}
MyFunction.prototype = SomeOtherFunction()
function SomeOtherFunction() {
return {
foo: function() {
return 'bar'
}
}
}
var fn = new MyFunction()
fn.foo()
// 3
function MyFunction() {}
MyFunction.prototype = SomeOtherFunction.prototype
function SomeOtherFunction() {
function Foo() {}
Foo.prototype.foo = function() {
return 'bar'
}
}
var fn = new MyFunction()
fn.foo()
I have JS object
var widget = {
check_balance: function(){...},
function_called_in_init: function(){
.....
this.check_balance();
};
};
this is code screenshot for better understanding..
and when it try to call this.check_balance(); it returns me error TypeError: this.check_balanceis not a function
the question would be - how to call function inside object which was also created inside object?
Also I can't init this function at the moment when all object is inited, becouse this is a recursion with ajax callback.
Its a little tricky to see what you are asking but the gist of it is you are looking to have the correct context. The tool for that is the whatever.bind(theContext) function. You pass in theContext to the object and that makes theContext object the context of whatever.
var parent = {
foo: function () {
var widget = {
check_balance: function(){ console.log('checking'); },
function_called_in_init: function(){
this.bar();
}.bind(this),
};
widget.function_called_in_init();
},
bar: function () {
console.log('bar');
},
};
parent.foo();
see fiddle
bind documentation
Use private function and closure
var widget = (function() {
var check_balance = function() {
//do what your check_balance has to do
}
return {
check_balance: check_balance,
function_called_in_init: function(){
.....
check_balance();
};
};
})();
Basically I looking for the ability to attach methods to an executable function while using the javascript prototype method. The code below demonstrates want I'm talking about and the functionality I'm looking for, but it is really a hack. Notice I have a valid this object to attach variables along with a main and init function.
function create(){
var $this = {},
main = function(){
prototype.main.apply($this,arguments);
};
prototype.init.apply($this,arguments);
//Add additional prototype methods by brute force, ugly
for(i in prototype)-function(i){
main[i]=function(){
prototype[i].apply($this,arguments);
}
}(i);
return main;
};
var prototype = {
//called when you create the object
init:function(text){
console.log('init');
this.text = text;
},
//called when you call the object
main:function(){
console.log('main');
console.log(this);
},
method:function(){
console.log(this.text);
}
};
//create returns a function that also has methods
//the below line will call the init method
var fun = create('some variables');
//call main function
fun();
//call methods
fun.method();
I'm afraid I might be missing something obvious.
Here is the same functionality as above, but instead extends the global function prototype.
Extending the global properties is bad practice, so I am looking for a alternative solution.
Function.prototype = {
//called when you create the object
init:function(text){
console.log('init');
this.text = text;
},
//called when you call the object
main:function(){
console.log('main');
console.log(this);
},
method:function(){
console.log(this.text);
}
};
function create(){
var ret = function(){
ret.main.call(main);
};
ret.init.apply(main,arguments);
return ret;
};
//create returns a function that also has methods
//the below line will call the init method
var fun = create('some variables');
//call main function
//fun();
//call methods
fun.method();
Just as an obvious point, it doesn't appear you can use the typical new object approach because if you call new you can't return a separate value.
Any explanation or considerations would be great!
You can put your the prototype functions into the "constructor" body. This technically is what you are currently doing, but defining them explicitly rather than using a helper method is much cleaner. Then, you can further simplify your code using the following pattern for public and private variables and methods:
function Fun(text) {
// This is the main function
var fn = function () {
return 'main';
};
// Attach public variables and methods
fn.publicVariable = 'public';
fn.publicMethod = function () {
return text; // text is a "private variable"
};
// Do whatever initialization
console.log('init');
// Return the main function
return fn;
}
var fun = Fun('this is some text'); // "init"
fun() // "main"
fun.publicMethod() // "this is some text"
console.log(fun.publicVariable); // "public"
console.log(fun.text); // undefined
By "the JavaScript prototype method", do you mean using the Function.prototype property to implement inheritance? Or are you just trying to create functions that have an initializer and attached methods?
Your example does the latter, so I'll assume that's what you you're looking for. Does this do what you're looking for?
function create(text)
{
var main = function()
{
console.log('main');
console.log(this);
}
var init = function()
{
console.log('init');
main.text = text;
}
main.method = function()
{
console.log(main.text);
}
init();
return main;
}
//the following line will call init
var fun = create('some variables');
//call main
fun();
//call methods
fun.method();