javascript初级问题

javascript对标点的要求,有时候少一个分号 ; 就不行,有时候没加引号 “” ,又不行,那么到底这些标点如何判断加不加?有没有要遵循的基本原则?

阅读 6.4k
13 个回答

记住以([/+-这五个字符开头的要加分号一般就够了。其它还有.,*%开头也要加分号,但是下面四个一般不会在开头,所以记住上面五个就一劳永逸了。如果想探究原理,可以看标准,里面有一节专门写了asi自动分号插入机制。

熬,还有引号,字符串加引号,标致符,保留字什么的不加。其它暂时没想起来!

JS 又不像 Python 用缩进来控制代码逻辑,JS 对于没有 ; 的代码会依次向后遍历直到语句通顺为止,

var
a
=
3

而且还不能造成歧义,

听说过不加 ; 的,还没听说过不加 ""的,引号是必须要的吧,求题主普及不加引号的。

新手怕出问题,建议还是手动加引号吧。

可以看看《effective JavaScript》第6条

如果你真的说的是很基础很基础的的意思,那我只能说多看多写,我刚接触编程的时候,觉得;就代表了一行代码的结束,所以当时恨不得每一行都来个;作为结束。举个例子,for(...){...}这个后面就没有;,再比如,if(){}后面也没有;,到现在我也不知道为什么这些后面没有;,但我觉得记住是这样写的就行了。至于“”,很好奇你说的不加“”就不行的例子,举个例子?

分号

js 中可以不加分号,但是推荐加。

分号是添加在一条语句 statement 的末尾的,基本和java,c等语言的要求类似。
注意,ECMA 规定function 声明不是一条语句,所以我们一般不在它的结尾加分号。

function foo() {
  // ...
}

但如果把一个函数赋值给一个变量,它又算是一个赋值语句,所以应该加分号。

var bar = function () {
  // ...
};

当然实际中没必要这么学院派,因为它并不影响程序运行,可加可不加,完全按照团队的代码规范来决定--如果有的话。

引号

当然如果你要声明一个字符串才加引号啊。单引号双引号都可以。但是一般推荐单引号。

PS 注意编程的时候切换你的输入法,分号得是英文输入法下的半角符号。;不是一个字符,解释执行的时候会报错的...

参考

分号书写的时候可有可无,因为解析器执行代码的时候会自动加上,至于引号,引号是引号声明字符串字面量的
var s="this is a string";
题主有见过这样声明字符串字面量的吗?

var s = this is a string;

这样解析器会吧s的值当成一个变量执行(例子中的变量名还是错误的)

不加分号就算了,还要写两行是什么鬼。。C,Java之类的不写就直接报错了

该加的加上总没错

如果语句不通顺,代码会遍历直到语句通顺为止;如果通顺了,没有加分号,默认在换行前会加上分号;引号有需要就加上去吧

分号:不加分号的在部分情况是可以的,具体是在于上下是浏览器默认能分得开是两块,否则浏览器解析的时候会将上下合成一个语句而导致报错,但如果不加分号进行js压缩的话,则会报错。
引号:不加引号的情况暂时没见过,不知道楼主说的是不是变量定义的时候,一般加上引号是字符串,但因为js是弱语言,不定义问题也不大,自己会根据不同情况进行转换,但这个还真很少情况能不加...

js是弱类型的语言,当然有些不规范也可以忍让,但是好的js代码都是要加符合规范,更好的有利于复用

其实说的简单点就是没有规范,你看书里面的代码是怎么添加那些符号的。建议你去看看javascript高级程序设计,虽然写的是高级程序设计其实也是一本入门的书,多看两遍你的收货更大

看到大家回应分号(;)问题觉得有趣,个人是"不用分号作语句结尾流派",也回一下提供另种参考。

先说明我并没有要大家都来不加分号,而是回答这个问题"为什么可以不加分号",或者是问"为何分号是选项可有可无?",或是"不加分号是在何时可以不加?何时又一定要加?何时又算多加了?"

"不用分号作语句结尾流派"并不是"完全不使用分号流派",而是该加的时候加,不该加的时候不加,大部份时候不用分号作为语句结尾。我如果在改写别人的旧代码或是像原本函式库(如jquery)的风格是有用分号(;)时,也是会加的,基本上自己写的就不用分号(;)结尾。

分号(;)是个议题,正反方都有。但这也不是标新立异、节省空间偷懒少打字,是有一些理由的,能真的这样灵活用,代表你真的理解在这是在作什么。下面说明有太多细节,有错请再提示提示。

用回车(\n)或断行来作为语句的结尾,与四种例外情况

分号(;)在其他语言就不说了,这里纯讨论js,在js里的分号(;)是什么作用?它既是语句(表达式)的分隔,也可以作为语句的结尾。纯粹认为分号(;)就一定是语句的结尾是有疑问的,下面这两个例子就是典型范例,也是很常见的错误:

//有问题的例子
function add() {
  var a = 1, b = 2;
  return
    a + b;
}

或是像下面这个,也是很常见的错误示范:

//有问题的例子
function test() {
  return
    {
      test: true
    };
}

这两例的函数回传值必为undefined,而不是应该回传的值3与物件。为何?因为你有看到return先换行,再接著要回传的值了吗?也就是说这两个代码在执行时,相当于下面这样的代码(我只写一个出来,另一例相同):

function test() {
  return;
  { test: true };
}

return因为先换行,视为语句结尾,所以根本没有可回传的值,也就是在上例子中,回车(\n)先把return结尾掉了,后面你加的分号(;)是结尾到下一行的。这逻辑代表回车(\n)在这一句语句结尾这功用上,比分号(;)还优先。

回车(\n)或空一行,为什么可以作为语句的结尾,来源是由于ECMAScript的自动插入分号(Automatic Semicolon Insertion)的标准。不过这标准是有特例的,在以下的4种情况是用回车(\n)或空一行是不会作自动插入分号来让语句作结尾,讲是说"特例",但大概也是每天都用到,只是常不知道为何是这样而已。大致说明如下:

1. 当这一行的语句是没关闭的情况,例如阵列、物件字面、圆括号之类,或是最后是个点号(.)或逗号(,)时,也就是如果把这行结尾,就会产生不合法语句的情况。

(注: 遇到等号(=)算未完整表述式如果指定值在下一行会略过自动结尾作用)

这种例子很常见,通常是在分开内容太长的语句,或是让值写得清楚的地方。我举下面的两个合法语法范例,你会很容易理解回车(\n)会在何时自动结尾,虽然这些例子都不好阅读:

//第一例
var a =
[ 1,
2,
3,
] 

//第二例
function test(a,
b,
c){
console.log(a,b,c
)
}

2. 这一行是++或--

这规则满怪异,从来没看过有人这样写过。js会认为++与--在这一行是要准备来运算执行下一行的值,所以不结尾。下面合法范例:

a=1
--
a
console.log(a)

3. 这一行是for()、while()、do、if()或else,但没有用花括号({})

这简写语法常见,每天都会用到。

if(null==undefined)
   console.log(true)
else
   console.log(false)

4. 下一行的开头是([)、(()、(+)、(*)、(/)、(-)、(,)、(.),或二进位运算子(例如~ & |),可以与这行组成一个表达式时。

function test(){
  return 1
         +2
         -3
}
console.log(test())        

下面这个例子刚好与第一点颠倒

var a = 
[1
,2
,] 

以上为用回车(n)作为自动插入分号(;)的4个特例。其他都会自动帮你作结尾。所以依这个逻辑,为何上面的return多了一行就会产生错误,另外与return有同样情况的还有几个,像continuebreakthrow,先回车然后在下一行再加分号也会已经自动插入分号。

[追加]第5情况: 空白语句。空白语句不会自动结尾。这与上面第3点相关是常见的错误。

//错误例子,不论if这行与else这行间有没有空一行都不会自动结尾
var i = 10

if (i === 5)

else  console.log(false)

你可以加上分号在if这行,会让语法合法可执行。个人有见过但相当少数。

//合法例子,但没人这样用的
var i = 10

if (i === 5);

else  console.log(false)

一定要使用分号的情况

分号(;)的用处不是只有语句结尾,它在某些语法有分隔表述式或语句的功用。以下情况必用分号(;),无论什么流派。

1. 最常见的是for语句中的三个表述式之间:

for(var i=0 ; i<10 ; i++)
{
 //... 
}

2. 在同一行写两个语句在一起,中间需要分号(;)。所以像case中如果break(或continue)写在同一行时,break前必加分号(;)

//第一例
var i = 0; i++ 

//第二例
case 'foo': doSomething(); break

3. 以[(开头的行,前面需要加分号(;)。这十分特别,这是一种保护防范的语法,有时候解译器或压缩工具会误认为开头()是要作函数呼叫或阵列或[]物件存取属性。另一情况是IIFE会认为是同一语句,IIFE刚好也是用(开头,所以这两种必加分号(;)在前面。参考: http://stackoverflow.com/ques...

//第一例
;(x || y).doSomething()
;[a, b, c].forEach(doSomething)

//第二例
var x = 42
;(function () { })()

"不需要"与"一定不能"使用分号的情况

接著要理解,什么时候必"不需要"与"一定不能"使用分号(;),这也很容易理解的。如果你是都要用分号来作每行语句的结尾,你应该了解一下。

1. for语句的最后一个(第三个)表达式后面。画蛇添足不多说。

//错误语法
for (var i=0; i < 10; i++;){}

2. 花括号的结尾(})的后面。但有例外,赋值时可以加分号(;)是对的语法。这个规则理论上应该是不需要加而已,经测试在chrome上也不会出错误讯息。这也画蛇添足不多说。

//不建议语法
function a(){};
if(){};

//正确语法,赋值时使用
var obj = {a:1};
var fun = function(){};

//正确语法,do...while
do {...} while (...);

3. 在if、for、while、或switch的圆括号结尾后面加上分号(;),这个合法语法,对照到最上面一节的第5例看看。

//错误例子,不过它合法
if (0 === 1); { alert("hi") }

//上例相当于下面这样
if (0 === 1);
alert("hi");

结语

要不要用分号(;)作为语句的结尾,就看个人习惯或组织团队规定的撰写风格了。不管如何,你应该理解为何分号(;)是选项而非必要的原因,不要因为大神说要加该加,就埋头拼命加,而不去理解为何要加。真实情况是并不是所有的情况分号作为语句都是选项,是有规则标准的。js程式语言虽然常常有坑与例外,但本质上是死的东西,上面的规则学好足以应付9成情况。

题外话是,开源专案中真的完全不使用分号(;)的专案虽不常见,最有名的是大家每天都在用的npm,还有最近比较火红的redux

最后1个小例子是请问下面这个合法的代码,它是相当于x;++y;还是x++;y;?三秒内说得出来代表你有认真看这篇回答。

x 
++ 
y

内容很多参考下面这两则文章来的,里面对js大神有批评的,不喜勿看:

推荐问题
宣传栏