返回函数和使用function.innerFunction有什么区别?

ily*_*lyo 4 javascript return function

这是一个关于我似乎遇到很多事情的一般性问题:我什么时候应该使用

function Bla(){return function(){alert("bla");}}
Run Code Online (Sandbox Code Playgroud)

并调用main函数Bla,何时使用

function Bla(){function innerBla(){alert("bla");}}
Run Code Online (Sandbox Code Playgroud)

并打电话Bla.innerBla

他们之间有什么区别?

And*_*ech 8

这是两种不同的做事方式,它们的运作方式不同.

第一个是返回另一个函数的函数.因此,要调用内部函数,首先需要调用外部函数,Bla(返回内部函数),然后调用返回值(内部函数):

function Bla(){
    return function(){
      alert("bla");
    }
}

Bla()(); // will alert "bla"
Run Code Online (Sandbox Code Playgroud)

第二个只是定义了一个内部函数,并且无法从外部函数外部调用该内部函数,因为它只在外部函数中作用域Bla:

function Bla(){
    function innerBla () {
      alert("bla");
    }
}

Bla(); // will do 'nothing'
Run Code Online (Sandbox Code Playgroud)

Bla.innerBlaundefined因为对象(函数是JavaScript中的对象)Bla没有一个名为innerBla附加到它的成员.


如果你想调用它bla.innerBla,你应该这样做:

function bla () { /* */ }

bla.innerBla = function () {
    alert("bla");
};

bla.innerBla(); 
// will alert "bla" because the `bla` object now has a member called `innerBla`.
Run Code Online (Sandbox Code Playgroud)

或者你可以有这样的东西(我经常使用的模式):

function bla () {
    return {
        innerBla: function () {
            alert("bla");
        }
    };
}

bla().innerBla(); // will also alert "bla"
Run Code Online (Sandbox Code Playgroud)

如果要使用构造函数pattern(new),则需要执行以下操作:

var bla = function () {
  this.innerBla = function () {
    alert("bla");
  };
};

var b = new bla();
b.innerBla();
Run Code Online (Sandbox Code Playgroud)

这相当于在OO语言中的对象实例上具有公共属性.


最后,如果你想innerBla通过每个'实例'(使用构造函数实现,即bla使用new关键字调用)来公开bla,你应该将函数添加到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"
Run Code Online (Sandbox Code Playgroud)

这与使用静态方法类似.


在旁注中,避免使用初始大写字母(pascal-case)命名函数,因为按照惯例,通常我们只使用new关键字(构造函数)来大写需要调用的函数.