Call function within prototype - javascript

<script type="text/javascript">
function Test()
{
console.log('constructor');
this.chaninFunction = function(){
console.log('chain me up');
}
}
Test.prototype.callme = function(first_argument) {
console.log('called him');
this.callBack = function()
{
console.log('call back');
}
};
Test.prototype.message = function(first_argument) {
console.log('message him');
};
var test = new Test();
test.chaninFunction();
test.callme();
test.callme().callBack(); //Error undefined
test.message();
</script>
Hi,
I am learning JS at the moment. having experience few situation.
Is there a way i can call the function within the prototype? the above testing i have done result in error. How can i access the function within prototype, or i can't?

It seems that you're saying you want to be able to chain the .callback() after a call to .callme().
Chaining is very simple. The previous method you called simply needs to return an object that contains the next method you want to call. So in your case, both methods are on the same object, so you just need to do return this;.
Test.prototype.callme = function(first_argument) {
console.log('called him');
this.callBack = function()
{
console.log('call back');
}
return this;
};

Related

How to call the same function repeatedly?

I want to call a function twice but not through the traditional way. A quick example of what I would be looking to do is below:
var myfunc = {
copy: function(message){
console.log(message);
}
}
myfunc.copy('hello').copy('world');
// result 'hello'
// result 'world'
Is this even possible?
Yes, but you should return the correct object:
var myfunc = {
copy: function(message){
console.log(message);
return this;
}
};
myfunc.copy('hello').copy('world');
// hello
// world
This technique is also known as Method chaining.
No, this will fail because .copy() doesn't return anything, so the second .copy() would throw an undefined error.
Try this:
var myfunc = {
copy: function(message){
console.log(message);
return this;
}
}
You need to chain this, You can also look up to jquerys $.fn how they create method chaining simply return this as this object is your myFunc variable and is used again by the next function
var myfunc = {
copy: function(message){
console.log(message);
return this;
}
};
myfunc.copy('hello').copy('world');
As other answers have pointed out, you need to return this in order to be able to call the same or additional functions on the same object.
You can do this a bit more easily (?) via a higher-order function which we will call "chainify", which takes care of returning this for you:
function chainify(fn) {
return function() {
fn.apply(this, arguments);
return this;
};
}
You can chainify your object methods in various ways, but here's one:
var myfunc = {
init: function() {
this.copy = chainify(this.copy);
return this;
},
copy: function(message){
console.log(message);
}
}.init();
This has the minor advantage that each and every method does not need to be cluttered with the return this at the end, and you don't run the risk of forgetting to do so.
It's called method chaining. Here's a blog that talks about this that you should be able to read and use to answer your question.
Basically you will need to use return this; to return the current object so the next method can use it.
// define the class
var Kitten = function() {
this.name = 'Garfield';
this.color = 'brown';
this.gender = 'male';
};
Kitten.prototype.setName = function(name) {
this.name = name;
return this;
};
Method chaining in JavaScript
This is known a Builder design pattern where in you cascade methods. Google it if it helps.

How can I run function automatically when calling object at each time?

How can I run function automatically when calling object at each time ?
I have the following object :
var myObject = {
main: function(e) {
//main
},
x: 1,
y: 2,
another: function(e) {
//another
}
}
Is it possible to achieve the below functionality?
Calling
myObject();
would call the main method.
But calling
myObject().another();
Would call the another method.
use only myObecjt() not myObecjt.main()
If I understood the question correctly, the code structure you're looking for is as follows:
var myObject = (function () {
var t = {};
t.main = function() {
console.log("main");
};
t.another = function () {
console.log("another");
};
t.main();
return t;
});
This will result in the following functionality:
Calling myObject(); will call the main method.
Calling myObject().another(); will call both the main and another methods.
if you are looking for jquery like chaining try something like this
function myObject(){
if(this == window){
return new myObject();
}
//whatever the main method does
return this;
}
myObject.prototype.x = 1;
myObject.prototype.y = 2;
myObject.prototype.another = function(){
//whatever the another method does
return this;
}
something like this, would recommend to investigate method chaining and prototypal inheritance, for a clean aplication of this.
or for something more simple
function myObject(){
//whatever the main method does
return myObject;
}
myObject.x = 1;
myObject.y = 2;
myObject.another = function(){
//whatever the another method does
return myObject;//method chaining may continue
}

Access prototype function within a prototype function

I'm trying to call login function defined in prototype but the function make the call (refresh) is also in the prototype.
function Checker() {
var self = this;
self.refresh();
window.setInterval(function(){self.refresh()}, 1000);
}
Checker.prototype = {
refresh: function() {
if(some condition){
login(); // this won't work, neither self.login();
}
},
login: function() {
}
};
How do I call login function within refresh function?
From a prototype method, the instance is set to this. So this.login() is what you want.
That's simple: Use this.login()

JS Module Pattern's public method as callback victim. (this-issue)

I spent the better part of the day reading about the module pattern and its 'this' scope. Eventually I found a work-around for my problem, although with a feeling there's a better way of doing things.
The actual code is >200 lines, but I've boiled it down to the following:
objA has a method (publicA) that objB wants invoke by callback. The detail that complicates things is that publicA needs help from publicA_helper to do its job. (http://jsfiddle.net/qwNb6/2/)
var objA = function () {
var privateA = "found";
return {
publicA: function () {
console.log("privateA is " + this.publicA_helper());
},
publicA_helper: function () {
return privateA;
}
};
}();
var objB = function () {
return {
callback: function (callback) {
callback();
}
}
}();
objA.publicA(); // privateA is found
objB.callback(objA.publicA); // TypeError: Object [object global]
Fair enough – I've grasped that the caller's context tends to influence the value of 'this'. So I add measures to retain 'this' inside objA, of which none seems to work. I've tried the
var objA = (){}.call({}) thingy, setting var self = this; (calling self.publicA_helper() accordingly). No luck.
Eventually, I added a private variable var self;, along with a public method:
init: function() {self = this;},
...and by making sure I call objA.init(); before passing objA.publicA to objB.callback, things actually work.
I cannot stress the immensity of the feeling that there's a better way of doing this. What am I missing?
The generalized solution is extremely simple.
Write all the module's methods as private, then expose those that need to be public.
I write all my modules this way :
var objA = function () {
var privateA = "found";
var A = function () {
console.log("privateA is " + A_helper());
},
var A_helper = function () {
return privateA;
}
return {
publicA: A
//A_helper need not be exposed
};
}();
Thus, all methods are in the same scope, each one having direct access to all other methods in the same module, and the ambiguous this prefix is avoided.
objB.callback(objA.publicA); will now work as expected.
See fiddle
I've tried the var objA = (){}.call({}) thingy,
How? You want to use call on the callback that you want to invoke with a custom this, not on your module closure. It should be
var objB = {
callback: function (callback, context) {
callback.call(context);
}
};
objB.callback(objA.publicA, objA);
I've tried setting var self = this;
The self variable is supposed to be in a closure and point to the object on the methods are stored. That is only this when your module IEFE would be invoked on your module - it's not. Or if it was a constructor - it's not. You could change that with call as above:
var objA = function () {
var privateA = "found",
self = this;
this.publicA = function () {
console.log("privateA is " + self.publicA_helper());
};
this.publicA_helper = function () {
return privateA;
};
return this;
}.call({});
But that's ugly. In your case, the self variable simply needs to point to the object literal which you're returning as your module:
var objA = function () {
var privateA = "found",
self;
return self = {
publicA: function () {
console.log("privateA is " + self.publicA_helper());
},
publicA_helper: function () {
return privateA;
}
};
}();
Btw, since you're creating a singleton you don't need an explicit self, you could just reference the variable that contains your module (as long as that doesn't change):
var objA = function () {
var privateA = "found";
return {
publicA: function () {
console.log("privateA is " + objA.publicA_helper());
},
publicA_helper: function () {
return privateA;
}
};
}();
Another method would be to simply make all functions private and then expose some of them - by referencing them local-scoped you will have no troubles.
var objA = function () {
var privateA = "found";
function publicA() {
console.log("privateA is " + helper());
}
function helper() {
return privateA;
}
return self = {
publicA: publicA,
publicA_helper: helper // remove that line if you don't need to expose it
};
}();
The reason is that the context is getting changed when you are invoking the callback. Not a generalized solution, but shows that the code works by specifying the context while invoking callback.
var objA = function () {
var privateA = "found";
return {
publicA: function () {
console.log("privateA is " + this.publicA_helper());
},
publicA_helper: function () {
return privateA;
}
};
}();
var objB = function () {
return {
callback: function (callback) {
callback.call(objA);
}
}
}();
objA.publicA(); // privateA is found
objB.callback(objA.publicA); // privateA is found

Javascript call nested function

I have the following piece of code:
function initValidation()
{
// irrelevant code here
function validate(_block){
// code here
}
}
Is there any way I can call the validate() function outside the initValidation() function? I've tried calling validate() but I think it's only visible inside the parent function.
function initValidation()
{
// irrelevant code here
function validate(_block){
console.log( "test", _block );
}
initValidation.validate = validate;
}
initValidation();
initValidation.validate( "hello" );
//test hello
Hope that you are looking for something like this
function initValidation()
{
// irrelevant code here
this.validate = function(_block){
// code here
}
}
var fCall = new initValidation()
fCall.validate(param);
This will work.
Hope this addresses your problem.
You can call validate from within initValidation. Like this.
function initValidation()
{
// irrelevant code here
function validate(_block){
// code here
}
return validate(someVar);
}
validate is not visible to anything outside of initValidation because of its scope.
Edit: Here's my suggestion of a solution.
(function() {
function validate(_block){
// code here
}
function initValidation()
{
// irrelevant code here
return validate(someVar);
}
function otherFunctions() {
// ...
}
// initValidation = function
}());
// initValidation = undefined
All of your functions will be hidden to anything outside the function wrapper but can all see each other.
This invocation will return function statement, which is function validate.
So you can invoke directly after the first invocation.
function initValidation() {
// irrelevant code here
return function validate(_block) {
// code here
}
}
initValidation()();
I know this is an old post but if you wish to create a set of instances that you wish to work with that reuse the code you could do something like this:
"use strict";
// this is derived from several posts here on SO and ultimately John Resig
function makeClassStrict() {
var isInternal, instance;
var constructor = function(args) {
if (this instanceof constructor) {
if (typeof this.init == "function") {
this.init.apply(this, isInternal ? args : arguments);
}
} else {
isInternal = true;
instance = new constructor(arguments);
isInternal = false;
return instance;
}
};
return constructor;
}
var MyClass = makeClassStrict();// create "class"
MyClass.prototype.init = function(employeeName, isWorking) {
var defaultName = 'notbob';
this.name = employeeName ? employeeName : defaultName;
this.working = !!isWorking;
this.internalValidate = function() {
return {
"check": this.working,
"who": this.name
};
};
};
MyClass.prototype.getName = function() {
return this.name
};
MyClass.prototype.protoValidate = function() {
return {
"check": this.working,
"who": this.name
};
};
var instanceBob = MyClass("Bob", true);// create instance
var instanceFred = MyClass("Fred", false);// create instance
var mything = instanceFred.internalValidate();// call instance function
console.log(mything.check + ":" + mything.who);
var myBobthing = instanceBob.protoValidate();
console.log(myBobthing.check + ":" + myBobthing.who);
I know this thread's been here for quite some time but I thought I'd also leave my 0.02$ on how to call inner functions from outside their scope (might benefit somebody).
Note that in any place, a better design decision should be taken into consideration rather than some hackish workaround which will bite you back later.
How about using function expressions instead of function statements and making use of the global scope.
var innerFn;
function outerFn() {
innerFn = function(number) {
return number ** 2;
}
}
outerFn();
console.log(innerFn(5));
// if there's more complex code around and you could write this defensively
if (typeof innerFn !== 'undefined') {
console.log(`we are squaring the number 5 and the result is: ${innerFn(5)}`);
} else {
console.log('function is undefined');
}
Or, you can make use of closures:
function outer() {
// initialize some parameters, do a bunch of stuff
let x = 5, y = 10;
function inner() {
// keeps references alive to all arguments and parameters in all scopes it references
return `The arithmetic mean of the 2 numbers is: ${(x + y) / 2}`;
}
return inner;
}
innerFn = outer(); // get a reference to the inner function which you can call from outside
console.log(innerFn());
Create a variable outside the parent function, then in the parent function store your required function in the variable.
Var Store;
Function blah() {
Function needed() {
#
}
Store = needed;
}
As a minor variation of Esailija's answer, I did this:
function createTree(somearg) {
function validate(_block) {
console.log( "test", _block );
}
if (somearg==="validate") { return validate; } // for addNodes
// normal invocation code here
validate(somearg);
}
function addNodes() {
const validate = createTree("validate");
//...
validate( "hello" );
}
createTree("create");
addNodes();
//validate("illegal");
so validate() is now perfectly shared between createTree() and addNodes(), and perfectly invisible to the outside world.
Should work.
function initValudation() {
validate();
function validate() {
}
}
Function definition:
function initValidation() {
// code here
function validate(_block){
// code here
console.log(_block);
}
return validate;
}
Call it as below:
initValidation()("hello");
function initValidation()
{
function validate(_block){
console.log(_block)
// code here
}
// you have to call nested function
validate("Its Work")
}
// call initValidation function
initValidation()

Categories