用嵌套函数和默认函数定义函数

Define a function with nested functions and default function

本文关键字:函数 定义 默认 嵌套      更新时间:2023-09-26

考虑以下代码:

function test() {
    this.foo = function() {
        console.log('foo');
        return;
    }
    this.bar = function() {
        console.log('bar');
        return;
    }
}
var action = new test();
action.foo();    //prints 'foo'

如果我需要在动作test中调用动作foobar,上面的代码可以很好地工作。然而,动作test本身应该是一个可调用的函数。我认为如果JavaScript允许我创建这样的东西(见下文)会很酷,但正如预期的那样,它说:

TypeError:操作不是的函数

function test() {
    this.foo = function() {
        console.log('foo');
        return;
    }
    this.bar = function() {
        console.log('bar');
        return;
    }
    return function() {
        console.log('default');
        return;
    }();
}
var action= new test();
action();        //prints 'default'
action.bar();    //printf 'bar'

有可能实现类似的目标吗?

这是可能的。只需在里面创建一个函数,并将其他属性直接添加到函数对象中:

function test() {
  
    var result = function () {
        console.log('default');
    };
  
    result.foo = function() {
        console.log('foo');
        return;
    }
    result.bar = function() {
        console.log('bar');
        return;
    }
    return result;
}
var test = new test();
test();        //prints 'default'
test.bar();    //printf 'bar'

在javascript中,也可以向函数添加属性。这样你就可以做这样的事情:

function test() {
    function defaultFn() {
       console.log('default');
    }
    defaultFn.foo = function() {
        console.log('foo');
        return;
    }
    defaultFn.bar = function() {
        console.log('bar');
        return;
    }
    return defaultFn;
}

虽然其他人指出这是可能的,但我只想指出,让构造函数返回一个不是new创建的实例的对象通常是一种糟糕的做法。

看看你的例子:

function Test() {
    this.foo = function() {}
    this.bar = function() {}
    return function() {}();
}
var test = new Test();

(我将您的test函数重命名为Test,因为这是一种大写函数的约定,您希望使用new调用它)

JS在调用new Test()时所做的是生成一个新的Object实例{},并将其作为this上下文传递到Test()函数中。默认情况下,这个对象也是调用new返回的对象。

因此,您正在做的是将foobar函数附加到新创建的对象。

然后return是一个不同的函数,然后从对new Test()的调用中返回,而不是从具有foobar的对象实例中返回……该对象只是丢失/垃圾回收。

这种"从构造函数返回不同的对象"是不好的做法,会导致混乱。此外,还会发生以下情况:

function Test() {}
var test = new Test();
test instanceof Test; // returns TRUE

但是,如果您返回其他东西:

function Test() {
  return function() {};
}
var test = new Test();
test instanceof Test; // returns FALSE (confusing!!!)

避开new,只做会更干净

function test() {
    var newFunc = function() {
        console.log('default');
        return;
    };
    newFunc.foo = function() {
        console.log('foo');
        return;
    }
    newFunc.bar = function() {
        console.log('bar');
        return;
    }
    return newFunc;
}
var t = test();
t();      // default
t.foo();  // foo
t.bar();  // bar

一旦创建该函数的实例,它就会调用下面的代码。类似于_constructor。

return function() {
        console.log('default');
        return;
    }();

我有如下内容:

function userClass(name, func) {
    this.name = name;
    this.func = func;    
}
function test(flag) {
    this.foo = function() {
        console.log('foo');
        return;
    }
    this.bar = function() {
        alert('bar');
        return;
    }
    return function() {
            var obj = {};
        obj["bar"] = new userClass("bar", function(){alert('bar');});
        alert('default');
        return obj;
    }();
}
var test = new test();
//test();        //prints 'default'
console.log(test);
test.bar.func();    //printf 'bar'

JSFiddle