Its a general question about something i seem to encounter a lot: When should i use
function Bla(){return function(){alert("bla");}}
and call the main function Bla
,
and when should I use
function Bla(){function innerBla(){alert("bla");}}
and call Bla.innerBla
?
What is 开发者_运维技巧the difference between them?
Those are two different ways of doing things, and they operate differently.
The first one is a function that returns another function. Thus, to invoke the inner function, you need to first call the outer one, Bla
, (which returns the inner one) and then invoke the returned value (the inner function):
function Bla(){
return function(){
alert("bla");
}
}
Bla()(); // will alert "bla"
The second one just defines an inner function, and there's no way of invoking that inner function from outside of the outer function because it's scoped only within the outer function Bla
:
function Bla(){
function innerBla () {
alert("bla");
}
}
Bla(); // will do 'nothing'
Bla.innerBla
is undefined
because the object (functions are objects in JavaScript) Bla
does not have a member called innerBla
attached to it.
If you want to invoke it like bla.innerBla
, you should do something like this:
function bla () { /* */ }
bla.innerBla = function () {
alert("bla");
};
bla.innerBla();
// will alert "bla" because the `bla` object now has a member called `innerBla`.
Or you can have something like this (a pattern that I frequently use):
function bla () {
return {
innerBla: function () {
alert("bla");
}
};
}
bla().innerBla(); // will also alert "bla"
If you want to use the constructor pattern (new
), you need to do something like this:
var bla = function () {
this.innerBla = function () {
alert("bla");
};
};
var b = new bla();
b.innerBla();
This is equivalent to having a public property on an instance of an object in an OO language.
And finally, if you want to expose innerBla
by every 'instance' (achieved using a constructor i.e. invoking bla
using the new
keyword) of bla
, you should add the function to bar.prototype.innerBla
:
var bla = function () { /* */ };
bla.prototype.innerBla = function () {
alert("bla");
};
var b1 = new bla(),
b2 = new bla();
b1.innerBla(); // will alert "bla"
b2.innerBla(); // will also alert "bla"
This is similar to having a static method.
On a side note, avoid naming functions with an initial capital case letter (pascal-case) because by convention, usually we only capitalize functions which need to be invoked using the new
keyword (constructors).
精彩评论