Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create method inside function

I am trying to create method inside a function. I can make this such a way:

function sample() {};
sample.show = function() { alert() };

And I'll see the alert calling sample.show();. But for the reason of code beautifying I want to move all method declarations inside functions. I tried that:

function sample() {
    sample.show = function() { alert() };
}

But I get: TypeError: Object function sample() has no method 'show' Another ways I tried:

function sample() {
    this.show = function() { alert() };
}
function sample() {
    sample.prototype.show = function() { alert() };
}
function sample() {
    this.prototype.method = function show () { alert() };
}

But result was the same. I can't even find any information about creating methods inside functions. Can you point me a right way?

UPD: I want to have ability to call sample() function which also does some stuff. So there are no solution in answers yet.

function sample() {
    this.show = function() { alert() };
    console.log('you called "sample()"');
}
sample(); // ==> you called "sample()"
like image 296
Vlad Holubiev Avatar asked Mar 20 '23 03:03

Vlad Holubiev


2 Answers

First attempt:

function sample() {
    sample.show = function() { alert() };
}

This would only create a "static" method on the sample function and only after executing it

console.log(sample.show);
//would show undefined on the console
sample();
console.log(sample.show);
//would then show the method definition as it has now been
//defined as a property of "sample"

Second Attempt:

function sample() {
    this.show = function() { alert() };
}

This will only work if you create a instance of sample

console.log(sample.show);
//will print undefined as there is no property "show" on sample
sample();
console.log(window.show);
//will print the function, but since sample was executed without a
//context, show is created as a property of the global object
//in this case "window"
var d = new sample();
console.log(d.show);
//will print the function as we now have a instance of sample which
//show was made a property of
console.log(sample.prototype.show);
//will show undefined as you are not actually creating the "show" method
//on the constructor sample's prototype

Now with the prototype version:

function sample() {
    sample.prototype.show = function() { alert() };
}

With this after you will be able to access the "show" method either through the instance or from the prototype chain, but for the prototype chain call to work you have to at least make one instance before hand

console.log(sample.prototype.show);
//will print undefined as "show" has not been defined on the prototype yet
var d = new sample();
console.log(d.show);
console.log(sample.prototype.show);
//Both will now print the function because the method has been defined

However the last one:

function sample() {
    this.prototype.method = function show () { alert() };
}

Will not work at all as you can not access the prototype directly from the instance you will get a undefined error once you try to create an instance.

For it to work you would have to go through the constructor chain to set the method

function sample() {
    this.constructor.prototype.method = function show () { alert() };
    //is the same as doing
    sample.prototype.method = function show(){ alert() };
}

So overall for your "beautifying" to work you have to call sample first, either directly, for the first one, or by creating an instance for the others.

like image 97
Patrick Evans Avatar answered Apr 01 '23 10:04

Patrick Evans


the code in the sample function will not be executed until sample is called. So you could get your example to work by doing this:

function sample() {
    sample.show = function() { alert() };
}

sample()
sample.show()
like image 27
steven Avatar answered Apr 01 '23 09:04

steven