【问题标题】:JavaScript function length and arguments properties/fieldsJavaScript 函数长度和参数属性/字段
【发布时间】:2015-08-30 11:33:56
【问题描述】:

虽然我有多年的 Java 经验,但我是 js 新手

我想当我声明一个函数时,它本质上是一种特殊类型的对象,并且有一些可以直接访问的内置字段,例如“arguments”和“length”

我注意到我可以访问函数范围内的“参数”之类的东西 即

function add(a,b) {
    return arguments[0]+arguments[1]
}

我也可以在范围之外访问诸如“长度”之类的东西

//2
alert(add.length)

上面的sn-p应该是正确的使用方式

然而

function sum(a,b) {
    // error
    return length
}

// null
alert(sum.arguments)

我认为参数和长度不是同一个基本的,是正确的想法吗?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~

经过一番研究,我找到了混乱的根本原因。 问题围绕着 JavaScript 中的属性 VS 变量

属性属于对象,而变量属于上下文。 这两个想法有时可以互换: 全局上下文恰好是窗口

<script>
   //property
   window.foo="a"
   //variable
   var bar="b"
   //a
   alert(foo)
   //b
   alert(bar)
</script>

在大多数情况下,比如函数上下文,它们是完全不同的想法,部分原因是您永远无法在代码中访问函数对象。因此,与全局设置相反,分配属性是不可能的!可能的只是在范围内声明一个变量

在我的问题中 “参数”是一个变量 而“长度”是一个属性 我没能区分这两个

更多信息,请参考 this post

【问题讨论】:

  • 此函数声明无效 javascript 。我想你应该看到arguments doc
  • @Haketo:除非您指的是最后一行代码,否则不确定您在说什么。前两个函数声明是有效的。 (调用时它们都可能会失败,第一个是因为arguments 上缺少s,第二个是因为可能没有范围内的length 变量,但是...)
  • @T.J.Crowder 你是在说那个function sum(a,b,){ 吗?因为这会抛出语法错误
  • @T.J.Crowder 只是一个错字,我的意思是参数
  • @Haketo:啊,错过了额外的,

标签: javascript


【解决方案1】:

函数是 JavaScript 中的对象。合适的,真实的物体。

length

函数的length 属性是它所具有的声明 参数的数量(这也称为函数的“arity”)。 add 的元数 (length) 是两个,因为您为它声明了两个正式参数:ab

arguments

arguments 伪数组不是函数对象的一部分。它是在调用函数时创建的对象,并且仅在该函数调用上下文的范围内。它包含函数实际调用的所有参数,这些参数可能与它声明的参数数量不同。对函数的每个单独调用都会获得自己单独的 arguments 对象。

在 JavaScript 的“松散模式”(它在 2009 年 ECMAScript 第 5 版规范之前的唯一模式)中,arguments 伪数组和声明的参数之间存在实时连接:

// In loose mode only
function foo(a) {
   console.log("a = " + a);
   console.log("arguments[0] = " + arguments[0]);
   a = 42;
   console.log("a = " + a);
   console.log("arguments[0] = " + arguments[0]);
}
foo(67);

在松散模式下,输出:

一个 = 67 参数[0] = 67 一个 = 42 参数[0] = 42

在“严格”模式(这是首选模式)下,该链接不存在(我们会在末尾看到 arguments[0] = 67),这对于 JavaScript 引擎的优化目的很有用。

【讨论】:

  • 看起来length就像一个类的传统字段,就像Java类中的一个字段,另一方面,参数从哪里来?
  • @user2670585: lengthobjectproperty,而不是类的字段。 (JavaScript 没有 Java 意义上的类。)arguments 来自调用函数的过程;它只是一个内置的东西,有点像在 Java 中你如何在实例方法中神奇地拥有 thissuper
【解决方案2】:

是的,长度和参数是不同的概念。

与 Java 不同,在 Java 中,对象、方法和局部变量的字段(属性)都可以在同一范围内访问(仅通过标识符),JavaScript 确实在范围变量(带有闭包,词法引用)和对象属性(可能继承)——不仅在概念上,而且在语法上。属性总是1通过.[] 表示法访问。

Function 实例中的.length 就是这样一个属性。你总是必须写add.lengthsum.length(或…["length"])。如果你只是在函数内部使用length,它不会自动引用属性——它是一个变量引用,在这种情况下是一个未声明的引用。

相比之下,arguments object 就像一个变量。它不能作为函数2 的属性访问。不可否认,它有点特别,因为你看不到变量的声明——它是在每个函数范围内隐式创建的。它有点像函数的第一行中有const arguments = {0: a, 1: b}; 语句。

1:不完全正确,有一个with statement 明确地将对象属性提升到一个范围内。它因其模棱两可而被鄙视,但在严格模式下已被弃用。
2:函数上还有一个已弃用的.arguments 属性,在严格模式函数抛出时访问它。如果在调用期间未访问,则为null

【讨论】:

  • 谢谢,你找到我了!你明白我的困惑围绕着两者的差异!
  • 我认为“长度”是一个函数的常见概念(因为函数是一个对象,而长度是一个属性),而“参数”是特殊的,它类似于隐式对象(例如会话,上下文)在一个JSP页面中,由容器管理(可能是js设置中的解释器)
  • 是的,arguments 很特别,但更像是一种具体化的反射形式。它不是 JSP 页面的全局会话或上下文,而是由每个函数调用创建的 - 就像 this 一样。
  • 我碰巧看到了一个非常棒的博客来澄清这个问题!!!! link
  • @user2670585:是的,很好,特别是详细说明全局对象的行为 - 规则总是有一个例外:-) 为了简单起见,我确实从我的答案中省略了它。但不要忘记,他所说的“VariableObject”只是一个实现细节,规范中类似的措辞只描述了预期的行为——实际的实现可能看起来完全不同。
猜你喜欢
  • 2022-11-02
  • 2013-07-03
  • 2023-03-25
  • 2013-12-21
  • 2012-07-18
  • 2018-10-08
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
相关资源
最近更新 更多