JS Function 函数表达式与函数声明语句
表达式和语句很基础,但是有时会犯错
function(){} // 报错 Function statements require a function name
(function(){}) // 不报错
function f(x){ return x + 1 }() // 报错 Unexpected token ')'
function f(x){ return x + 1 }(1) // 不报错,为什么返回 1
解释
- 因为 JavaScript 将 function 关键字当作一个 函数声明语句 的开始,而函数声明语句 function 关键字后面应该是 函数名,这里后面跟圆括号,当然会报错
- 给它加上一对圆括号,解析器会把
()
里的当做表达式去解析,在这里就会当做匿名函数表达式解析,所以不会报错。 - 在一条语句后面加上
()
会被当做分组操作符,分组操作符里必须要有表达式,所以这里报错 - 在一条函数声明语句后面加上
(1)
,仅仅是相当于在声明语句之后又跟了一条毫无关系的表达式
javaScript 中的表达式和语句是有区别的,一个表达式会产生一个值,它可以放在任何需要一个值的地方,javaScript 语句可以理解成一个行为,某些需要语句的地方,你可以使用一个表达式来代替.这样的语句称之为表达式语句。
If 语句和条件运算符
var x
if (y >= 0) {
x = y
} else {
x = -y
}
等价于
var x = (y >= 0 ? y : -y)
在等于号和分号(省略了) 之间的代码就是条件表达式
两边的小括号不是必需的,但我觉得小括号能让条件表达式更易读。
逗号运算符
要想连接两个表达式,使用的是不常见的逗号运算符(返回最后一个表达式的值)
var x = ("a", "b", "c")
// 'c'
对象字面量和语句块
下面是一个对象字面量,也就是一个可以生成一个对象值的表达式。
{
foo: bar(3, 5)
}
你也许会感到震惊,那就是 JavaScript 居然可以有独立的代码块(常见的代码块是依托于循环或者 if 语句的)
下面的代码演示了这种代码块的作用:你可以给它设置一个标签然后跳出这个代码块。
function test (printTwo) {
printing: {
console.log('One')
if (!printTwo) break printing // 跳出代码块
console.log('Two')
}
console.log('Three')
}
test(false)
// One Three
test(true)
// One Two Three
函数表达式和函数声明
下面的代码是一个函数表达式:
function () { }
// 你还可以给这个函数表达式起一个名字,将它转变为一个命名(非匿名) 的函数表达式
function foo() { }
// 这个函数的函数名(foo) 只存在于函数内部,比如,可以用它来做递归运算
一个命名的函数表达式从表面上看起来,和一个函数声明并没有什么区别,但他们的效果是不同的:一个函数表达式产生一个值(一个函数)
一个函数声明执行一个动作:将一个函数赋值给一个变量,此外,只有函数表达式可以被立即调用,函数声明不可以。
解决冲突
为了解决对象字面量和语句块以及函数表达式和函数声明这种歧义,JavaScript 语法禁止表达式语句以大括号或关键字 function 开头
如果你想写一个以那些标志开头的表达式语句,该怎办呢? 你可以把它放在一个括号内部,这样并不会改变运行结果,只会确保该表达式被解析在表达式上下文中。
eval("{ foo: 123 }")
// 123
eval("({ foo: 123 })")
// { foo: 123 }
(function () { return "abc" }())
// 'abc'
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: 函数递归的几种方式
下一篇: TypeScript 常见问题
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论