Nodejs 下面这个函数为何无法调用?

Nodejs 下面这个函数为何无法调用?

x.test()调用为何会报错? y.test()却是没问题的?

var x=function(val){
	console.info('the value is: ', val);

	function len(val){
		if (typeof val=='undefined'){
			console.info('no source path specified')
		}
		console.info('nested len function called from ', val);
	}

	var test=function(){
		console.info('test');
	}
}

var y={
	test:function(){
		console.info('function defined in y');
	}
}

x('haha');
x('jindezhen');
console.info(typeof x.len);

y.test();

// x.test();

6 回复

要理解为什么 x.test() 调用会报错而 y.test() 却没有问题,我们需要仔细分析提供的代码。

问题分析

  1. 变量 x 的定义

    var x = function(val) {
        console.info('the value is: ', val);
    
        function len(val) {
            if (typeof val == 'undefined') {
                console.info('no source path specified');
            }
            console.info('nested len function called from ', val);
        }
    
        var test = function() {
            console.info('test');
        }
    }
    

    在这里,x 是一个函数。当我们通过 x('haha')x('jindezhen') 调用它时,它会被执行,并且内部的 lentest 函数也会被定义。但是,这些函数仅在当前执行上下文中可用,一旦函数执行完毕,它们就会被销毁。因此,当我们尝试访问 x.lenx.test 时,它们实际上是未定义的。

  2. 变量 y 的定义

    var y = {
        test: function() {
            console.info('function defined in y');
        }
    }
    

    在这里,y 是一个对象,它有一个名为 test 的方法。当我们调用 y.test() 时,它直接访问了对象 y 中的 test 方法,这是合法的。

示例代码

var x = function(val) {
    console.info('the value is: ', val);

    function len(val) {
        if (typeof val == 'undefined') {
            console.info('no source path specified');
        }
        console.info('nested len function called from ', val);
    }

    var test = function() {
        console.info('test');
    }
}

var y = {
    test: function() {
        console.info('function defined in y');
    }
}

x('haha'); // 输出: the value is:  haha
x('jindezhen'); // 输出: the value is:  jindezhen
console.info(typeof x.len); // 输出: undefined
console.info(typeof x.test); // 输出: undefined

y.test(); // 输出: function defined in y

// x.test(); // 这行代码会导致错误,因为 x.test 是未定义的

解决方案

如果你希望在 x 函数外部能够调用 test 方法,你可以将 test 方法定义为 x 对象的方法:

var x = function(val) {
    console.info('the value is: ', val);

    function len(val) {
        if (typeof val == 'undefined') {
            console.info('no source path specified');
        }
        console.info('nested len function called from ', val);
    }

    this.test = function() {
        console.info('test');
    }
}

x('haha'); // 输出: the value is:  haha
x('jindezhen'); // 输出: the value is:  jindezhen
console.info(typeof x.test); // 输出: function

var obj = new x('someValue'); // 创建一个实例
obj.test(); // 输出: test

这样,你就可以在外部通过实例调用 test 方法了。


y像个字典,不像函数,不过里面却有函数 x就是个函数,我想让它变得像字典,可是

没办法通过函数名称访问到内部的test变量,这是为啥?

这个不是函数对象内部的一个变量么?肿么就不能访问?

如果把function当成class,按其他语言的理解,test应该也是成员变量啊,

#咋就不能访问呢?

x函数里,test是局部变量,一旦出了x函数的作用域就没用了 y是个object,test是它的一个属性,这个属性对应的是一个函数,所以当然可以在外部调用

JavaScript和其他典型的面向对象的语言是不同的,不能按照其他语言的思路来理解JavaScript代码。楼主可以查下JavaScript变量作用域的资料来了解一下。

就这个问题来说,函数内部定义的变量只能在该函数内部使用,如果想在外部访问到的话,可以用return把它返回出去,这样在外部执行函数的时候就能得到这个变量的值了。

代码修改如下:

var x=function(val){
    console.info('the value is: ', val);
    function len(val){
        if (typeof val=='undefined'){
            console.info('no source path specified')
        }
    console.info('nested len function called from ', val);
    }
    var test=function(){
        console.info('test');
    }
return test; //将内部变量传递出去

}

x(‘haha’)(); //执行内部变量定义的函数

输出结果为: the value is: haha test

你可以这样理解, 你爸有个晚辈,这个晚辈是你,可以说有你爸就有你, 你爸有个晚辈,是村里老王的儿子,但是你不能说有你爸就有老王的儿子吧。

在这个例子中,x 是一个普通函数,而不是对象。当你定义 x 时,lentest 函数都是在其局部作用域内定义的。因此,它们不能直接通过 x.test() 来访问。

你可以通过修改 x 的定义方式,使其成为一个对象或者使用闭包来访问这些方法。以下是两种解决方案的示例:

方案一:将 x 定义为对象

var x = {
    test: function (val) {
        console.info('the value is: ', val);

        function len(val) {
            if (typeof val == 'undefined') {
                console.info('no source path specified');
            }
            console.info('nested len function called from ', val);
        }

        var test = function () {
            console.info('test');
        }
    }
};

x.test('haha');
x.test('jindezhen');

方案二:使用闭包

var x = function (val) {
    console.info('the value is: ', val);

    function len(val) {
        if (typeof val == 'undefined') {
            console.info('no source path specified');
        }
        console.info('nested len function called from ', val);
    }

    return {
        test: function () {
            console.info('test');
        }
    };
};

var instance = x('haha');
instance.test();

在这两个方案中,x.test() 都可以正常工作。第一个方案是直接将 test 方法作为对象的方法暴露出来;第二个方案则是返回一个包含 test 方法的对象,并通过实例调用该方法。

回到顶部