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();
要理解为什么 x.test()
调用会报错而 y.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); } var test = function() { console.info('test'); } }
在这里,
x
是一个函数。当我们通过x('haha')
或x('jindezhen')
调用它时,它会被执行,并且内部的len
和test
函数也会被定义。但是,这些函数仅在当前执行上下文中可用,一旦函数执行完毕,它们就会被销毁。因此,当我们尝试访问x.len
或x.test
时,它们实际上是未定义的。 -
变量
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
时,len
和 test
函数都是在其局部作用域内定义的。因此,它们不能直接通过 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
方法的对象,并通过实例调用该方法。