我最近一直在尝试学习 javascript 并有几个问题。
创建函数表达式时:
var greet = function(){
console.log('Hi');
}
是创建函数对象并让变量“greet”指向内存中的函数对象吗?
我的第二个问题,如果你有这样的功能:
function log(a){
console.log(a);
}
然后调用该函数:
log(greet); //greet is the function expression declared above.
所以我知道当创建一个函数对象时,有两个属性被赋予该对象。名称(如果提供,否则为匿名)和代码属性,用于存储函数括号内包含的代码。现在我对日志函数中的参数“a”在函数对象中的附加位置感到有点困惑。 “a”只是函数对象日志的另一个属性,它只是指向传递给日志函数的任何内容的内存地址吗?在这种情况下,它是一个名为 greet 的函数表达式。任何输入将不胜感激。谢谢!
最佳答案
当一个函数被调用时:
log(greet)
然后标识符 log 在当前执行上下文中解析,如果没有找到,则沿着作用域链搜索,在全局执行上下文结束。如果未找到,则会抛出错误。
在这种情况下,log 已使用函数声明定义,因此它存在于全局范围内,因此可以找到。检查它的值以确保它是可调用的(同样,如果不是,则会抛出错误)如果是,则调用它。
在调用中,标识符greet 被解析并将其值传递给函数。如果 greet 无法解析(即它不存在于作用域链中),则会抛出错误。在这种情况下,它解析为对分配给 greet 的函数的引用。
当执行log 时,会创建一个新的执行上下文。 log 的函数声明定义了一个形参 a(在其形参列表中),因此 a 被创建为 记录。调用中的值按顺序传递给形参列表中的标识符,因此greet的值被赋值给a。请注意,每次调用函数时都会初始化和创建新的执行上下文。
调用时遵循相同的过程:
console.log(a);
因此在 console.log 中,对 greet 的引用作为第一个参数传递,因此它现在引用 greet 函数。
console.log 的行为完全依赖于实现,因此内部结构是未知的,但对于函数来说,大多数倾向于只调用函数的 toString 方法。
ECMAScript 的一个方便的特性是,参数对象是由传递给函数的参数创建的,因此如果没有要分配给它们的参数,则传递的值始终可用作参数对象的数字属性。所以 console.log 不必定义任何形式参数,它可以只遍历其 arguments 对象并依次处理传递的值。
关于Javascript 函数表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33182772/