javascript 函数是对象吗?
我在 Javascript 问题上苦苦挣扎了一段时间,但在网上找不到解释。我想这是因为我没有输入正确的关键字,这也可能与我为此苦苦挣扎的原因有关。
我的基本假设是可以改变对象:
> var x = {'n': 2};
> x['n']
2
> x['n'] = 3;
3
唷,这有效。但仍然(函数也是对象):
> var addn = function(a) {
var n = 2;
return n + a;
}
> addn(3);
5
> addn['n'] = 3;
3
> addn(3);
5
这次我无法更改“n”。有没有办法在保持功能性风味的同时解决这个问题?而不是完全面向对象。我遇到的一个相关问题是如何维护函数的依赖关系以进行测试——同样不需要面向对象?当然,我正在寻找解决方案,但如果可能的话,我还想了解 Javascript 中的哪种机制让我陷入困境。
干杯,
马克
免责声明: 通过提及面向对象,我并不是有意反对面向对象。我也无意说任何反对 VI 或 Emacs 的话。如果我以某种方式伤害了你的感情,请跳过这一点。
I am struggling with a Javascript question for some time now and I was not able to find an explanation on the web. I guess it is because I do not enter the right keywords which might also be related to why I am struggling with this at all.
My basic assumption is that it is possible to alter objects:
> var x = {'n': 2};
> x['n']
2
> x['n'] = 3;
3
pheww that worked. But still (functions are objects, too):
> var addn = function(a) {
var n = 2;
return n + a;
}
> addn(3);
5
> addn['n'] = 3;
3
> addn(3);
5
This time I was not able to change 'n'. Is there a way to fix this while keeping the functional flavor? As opposed to going fully OO. A related question I have would be how to maintain dependencies of functions for the purpose of for example testing - again w/o going OO? Of cause I am looking for a solution but if possible I would also like to understand which mechanism in Javascript makes me struggling.
Cheers,
Mark
Disclaimer:
By mentioning OO I do not intent to say anything against OO. And I do not intent to say anything against VI or Emacs either. If I somehow hurt your feelings please skip this one.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
函数作用域中的私有变量和对象的属性是两个截然不同的东西。该函数内部的 var n 完全无法从该函数外部访问。
因此,在该代码运行后,
addn.n == 3
,但每次函数运行时都会初始化设置为var n
的不同值。由于 javascript 的怪癖,函数无法真正轻松地访问它自己的属性。相反,通过传入参数 function(n, a)或使用对象来实现类似的功能,可以更好地实现此模式。
Private variables in a function scope, and a property of an object are 2 very different things.
var n
inside that function is completely inaccessible from outside that function.So after that code runs,
addn.n == 3
, but the different value set tovar n
is initialized every time the funciton runs. Due to the quirks of javascript, a function can't really access it own properties very easy. Instead this pattern would be better achieved by passing in an argumentfunction(n, a)
Or use an object to achieve something similar.
如果我正确理解你的问题,你可以为你的匿名函数命名并通过它访问函数对象的属性:
If I understand your question correctly, you can give a name to your anonymous function and access the function object's properties through that:
对象属性和局部变量在很大程度上不相关:
var n
声明一个变量,该变量是作用域为它所在的函数(即
在那之外是不可见的
函数(通过闭包除外))。
addn['n']
添加名为n
的属性到
addn
并相当于addn.n
Object properties and local variables are largely unrelated:
var n
declares a variable that isscoped to the function it's in (i.e.
it is not visible outside of that
function (except via closure)).
addn['n']
adds a property namedn
to
addn
and is equivalent toaddn.n
由于 JavaScript 具有函数作用域,因此您可以使用函数来存储 n 的值,如下所示:
Since JavaScript has function scope, you can use a function to store the value of n like so:
最好完全忘记 Javascript 领域中“对象”的传统 OO 概念,并从闭包的角度进行思考。我强烈建议阅读 jQuery 的创建者 John Resig 撰写的本教程。
It's best to forget completely about the traditional OO concept of "objects" in Javascript-land, and to think instead in terms of closures. I strongly recommend reading this tutorial by John Resig, the creator of jQuery.
首先,您不会通过执行以下操作来更改函数变量:
您定义的函数没有任何名称(也称为“匿名函数”)。您只需将该函数分配给一个名为
addn
的变量即可。变量没有任何属性 - 它只是一个容器(除非变量引用数组)。所以addn['n']
什么也不返回。正如用户
casablanca
所指出的,您可以将函数命名为func
,然后访问(和修改)其属性为func。
func。属性名称>
。First, you are not changing the function variable by doing this:
The function you defined does not have any name (also known as "anonymous function"). You are simply assigning that function to a variable called
addn
. A variable does not have any property- it is simply a container (Unless the variable refers to an array). Soaddn['n']
returns nothing.As user
casablanca
noted, you can name your function asfunc
and then access (and modify) its properties asfunc.<propertyname>
.每个函数都有一个
范围
,基本上是函数被调用的位置/方式。当函数被调用时,它会创建一个新的函数执行上下文,并将其推送到调用堆栈上;在语言读取该行/语句之前,该上下文中不存在任何内容,而在调用函数之前不会发生这种情况。您所做的是将一个值分配给函数的 PROPERTY,而不是访问该范围内的变量
n
。您无法从外部作用域访问内部作用域,因为外部作用域不存在内部作用域但是您可以从外部作用域访问外部作用域内部作用域,因为外部作用域存在于内部作用域中。
另外,这里有一点仅供参考。
JavaScript 是基于
原型
的;不基于class
。 JavaScript 中的一切都是对象,甚至是函数。阅读本文以了解更多关于原因的信息(这是 Quora 上的一篇很好的文章) - https://www.quora.com/Why-is-function-an-object-in-JavascriptEvery function has a
scope
, basically where/how the function gets called. When a function gets called, it creates a new function execution context pushes it on the call stack; nothing in that context exists until that line/statement is read by the language, which won't happen until the function gets called.What you were doing was assigning a value to the PROPERTY of the function, not accessing the variable
n
in that scope.You cannot access an inner scope from an outer scope because the inner scope does not exist to the outer BUT you can access an outer scope from an inner scope because the outer scope exists to the inner scope.
Also, here is a bit of an FYI.
JavaScript is
prototype
based; notclass
based. EVERYTHING in JavaScript is an object, even functions. Read this to learn more about why that is (it's a good post on Quora) - https://www.quora.com/Why-is-function-an-object-in-Javascript基本上,Javascript 中的一切都是对象。如果您说
对“a”的引用仍将返回 3,但 a 也有一个值为 4 的成员“n”。因此,当您说
addn['n'] = 3
时,您正在添加一个添加新成员,并且不会以任何方式影响功能。我强烈建议阅读 良好的 C 习惯如何会鼓励不良的 JavaScript 习惯。 在描述所有可能做错的事情时,这是对 Javascript 中对象工作方式的一个很好的介绍。
Basically, everything in Javascript is an object. If you said
references to 'a' would still return 3, but a also has a member 'n' which has value 4. So when you say
addn['n'] = 3
you are adding a new member to addn, and not affecting the function in any way.I strongly recommmend reading How good c habits can encourage bad javascript habits. In describing all the things you can do wrong, it's a great intro to the way objects work in Javascript.