JavaScript函数长度和参数属性/字段

JavaScript function length and arguments properties/fields

本文关键字:属性 字段 参数 函数 JavaScript      更新时间:2023-09-26

我是js的新手,尽管我在Java 方面有多年的经验

我想,当我声明一个函数时,它本质上是一种特殊类型的对象,并得到了一些可以直接访问的内置字段,如"arguments"answers"length">

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

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

此外,我可以访问范围外的类似"长度"的内容

//2
alert(add.length)

上面的代码片段应该是使用的正确方法

然而

function sum(a,b) {
    // error
    return length
}
// null
alert(sum.arguments)

我想论点和长度不一样,这是正确的想法吗?

~~~~~~ ~

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

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

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

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

在我的问题中"arguments"是一个变量而"长度"是一个属性我没能区分两个

有关更多信息,请参阅这个帖子

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

length

函数的length属性是它所拥有的声明的参数的数量(这也被称为函数的"arity"(。add的arity(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);

在松散模式下,输出:

a=67arguments[0]=67a=42arguments[0]=42

在"严格"模式(这是首选模式(中,该链接不存在(我们在末尾看到arguments[0] = 67(,这对JavaScript引擎的优化非常有用。

是的,长度和自变量是不同的概念。

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

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

相比之下,arguments对象的工作方式类似于变量。它不能作为函数2的属性访问。诚然,它有点特殊,因为您看不到变量的声明——它是在每个函数范围中隐式创建的。它的工作方式有点像函数的第一行中有一个const arguments = {0: a, 1: b};语句。

1:不完全正确,有一个with语句显式地将对象属性提升到一个范围中。由于其模糊性,它受到了蔑视,但在严格模式下遭到了抨击
2:函数上还有一个不推荐使用的.arguments属性,在严格模式函数抛出时访问它。如果在调用期间未访问,则为null