新人 JavaScript 求助语法问题

2022-05-26 10:29:47 +08:00
 fenglala
function sleepPromise() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log("promise")
        }, 1000)
    })
}

sleepPromise() // 这里没有分号

    (function () {
        console.log("hhh")
    })()

为啥调用 sleepPromise()的时候不加分号,就会跑不起来,加了分号就可以了

PS C:\Users\lala\Downloads> node c.js
C:\Users\lala\Downloads\c.js:11
    (function () {
    ^

TypeError: sleepPromise(...) is not a function
    at Object.<anonymous> (C:\Users\lala\Downloads\c.js:11:5)
    at Module._compile (node:internal/modules/cjs/loader:1105:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12)
    at node:internal/main/run_main_module:17:47

加了分号之后

function sleepPromise() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log("promise")
        }, 1000)
    })
}

sleepPromise(); // 这里有分号

    (function () {
        console.log("hhh")
    })()
PS C:\Users\lala\Downloads> node c.js
hhh
promise

我会 C ,但是不会 JavaScript ,求指教,感谢!

2922 次点击
所在节点    JavaScript
26 条回复
Baymaxbowen
2022-05-26 10:32:54 +08:00
下面自执行函数的问题
renmu123
2022-05-26 10:34:37 +08:00
大概是因为被解析成这样了 sleepPromise()(function...)()
function..被当成了函数 sleeppromise 的参数,sleeppromise 又不是函数所以加报错了
noe132
2022-05-26 10:35:44 +08:00
a()
(b)()
其实是 a()(b)()
a();
(b)()
才是 a();(b)()
这是自动分号插入的机制。括号开头的行会有这个问题。
wangxiang
2022-05-26 10:36:27 +08:00
论写分号的重要性
shintendo
2022-05-26 10:36:34 +08:00
搜索关键词:javascript ASI
ipwx
2022-05-26 10:40:54 +08:00
horseInBlack
2022-05-26 10:42:21 +08:00
和 promise 没关系,这样写也就会报错

function testFunction(){
console.log('test')
}

testFunction()

(function () {
console.log("hhh")
})()

报的是 Uncaught TypeError: testFunction(...) is not a function
也就是说 JS 认为 testFunction()返回了一个函数,然后这个函数执行的参数是

function () {
console.log("hhh")
})(

而不是预期的作为立即执行函数执行

加上分号以后 JS 就知道那句话结束了,不会连在一起执行

所以写代码的时候可以配合自动格式化工具,团队的话可以共用一套规则

理论上来说加上分号减少了 JS 分析分词的步骤效率更高,减少歧义,而且自动执行的事也不费什么事
TomatoYuyuko
2022-05-26 10:42:55 +08:00
首先编译的时候浏览器会帮你补分号,然后识别你的代码,你的这块代码是:sleepPromise()(function () {console.log("hhh")})(),浏览器看你这么写麻了,他也不知道该怎么断句了,因为有歧义,所以要加
daimubai
2022-05-26 10:53:03 +08:00
在大多数情况下,换行意味着一个分号。但是“大多数情况”并不意味着“总是”!

JavaScript 无法确定是否真的需要自动插入分号的情况

alert("Hello")

[1, 2].forEach(alert);

这种情况也会报错。

来源 https://zh.javascript.info/
Shy07
2022-05-26 10:53:20 +08:00
除了 ( ,还有 [ 和 `,这三个符号作为行首,建议前面加分号

可以参考这个: https://standardjs.com/rules-zhcn.html#%E5%85%B3%E4%BA%8E%E5%88%86%E5%8F%B7
shakukansp
2022-05-26 10:55:10 +08:00
举个例子
const fn = () => {
return function () {}
}

fn()() 什么意思
fn()(function () {
console.log("hhh")
})什么意思
fn();()什么意思
fn();(function () {
console.log("hhh")
})什么意思

自己想想
Justin13
2022-05-26 10:55:59 +08:00
不会走,就想跑,老老实实加分号不好么
fenglala
2022-05-26 10:56:02 +08:00
看懂了,感谢大家的回复!

我搞了个让不加分号也能跑起来的例子,虽然实际代码中想表达的不是这个意思,但是让我理解了:

function returnFunction() {
console.log('function return function return function')
return () => {
console.log('function return function')
return () => {
console.log('function')
}
}
}

returnFunction()
(function () {
console.log("hhh")
})()
Leviathann
2022-05-26 11:00:59 +08:00
立即执行函数前面必须加分号
molvqingtai
2022-05-26 11:02:27 +08:00
原因楼上都说了,建议使用 eslint 或 prettier ,如果配置无分号的风格,会自动在有歧义的语句上加上分号
MegrezZhu
2022-05-26 11:04:45 +08:00
所以说分号是多么重要……
july1995
2022-05-26 11:09:48 +08:00
14 楼加 1 。 立即执行函数前需要加分号。 具体为啥 老师讲了,没记住,就记住了一个结论了。
Pastsong
2022-05-26 11:10:27 +08:00
+(function () {})()
前面写个+也是可以的,如果你真的很讨厌分号
cheneydog
2022-05-26 11:15:33 +08:00
学到了
libook
2022-05-26 11:21:48 +08:00
https://262.ecma-international.org/5.1/#sec-7.9

官方文档里面说明了自动补充分号的思路,你需要在省略分号的同时,确保代码不会产生歧义,自己做的话可能会有些心智负担,除非你用 StandardJS (注意这只是个工具名称,并不真的是 JS 的 Standard )之类的 Linter ,可以帮你自动规避不写分号会产生歧义的情况。

但我个人推荐能写分号的地方都写分号,特别是可能会涉及到代码 minification 的情况,你源代码执行的时候可能自动补充分号是正常的,但 minify 之后很可能就会出现问题。

分号的存在就是为了避免歧义的情况,因为 JS 不靠缩进和换行来表示表达式的终止或层级关系,有些情况下无法避免写分号,刻意不写分号的意义就不那么大了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/855376

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX