目录
前言
javascript的语法非常简单,本章介绍它的注意事项!
简单
1 语句和表达式
本节介绍语句和表达式的区别,但不是全部。
语句
粗略的说,一条语句执行一个动作;常见的语句比如for语句和if语句;程序是一系列语句组成的。(javascript按行执行。因此,为使你的代码更加规范,一般一行就是一个语句)
//这是一个赋值语句
var a = 1 + 2;
表达式
表达式产生值;它们是函数参数,赋值的右侧等;任何javascript预计为值的地方,都可以使用表达式。
//这是一个表达式
3 * 7
2 区块和分号
区块
区块是由大括号包围的语句序列;你可能会惊讶javascript拥有独立的代码块,但这并不能构成单独的作用域;区块往往用来构成其他更复杂的语法结构,包括:
- 循环:for,while(但不是do-while)
- 分支:if,switch,try
- 函数声明(但不是函数表达式)
//一个简单的代码块
{
var a = 13;
}
//if语句
var b =1;
if(b===1){
b =2;
}
else{
b=3;
}
//while和do-while
var a = 2;
while (a > 0) {
a--;
} // 不带分号
do {
a--;
} while (a > 0);//带分号
//for语句,块内部的参数
for(var i=1;i>3;i++){
var b = 2;
}
console.log(b);//2 区块不构成单独的作用域
console.log(i);//1
//函数声明和表达式
function test(){
} var a = 1; //不带分号
var f = function () { }; var a = 1; // 加分号
分号
分号的基本使用规则是:
- 通常,语句以分号结尾。
- 例外是以块结尾的语句。
分号在JavaScript中是可选的。通过所谓的自动分号插入(ASI;其他篇幅讲介绍^)添加缺少的分号。但是,该功能并不总是按预期工作,这就是为什么你应该总是包含分号。
如果在块之后添加分号,则不会出现语法错误,因为它被视为空语句。
//空语句
;;;
分号终止语句,但不终止块。在一种情况下,您将在块之后看到分号:函数表达式是以块结尾的表达式。如果这样的表达式在语句中排在最后,则后面跟一个分号
//函数表达式
var f = function () { }; var a = 1; // 加分号
//报错举例
var f = function () { } var a = 1;//代码写在同一行防止触发分号自动插入机制
3 标识符
标识符规则
标识符是用于命名事物并在JavaScript中以各种话音未落角色出现。例如,变量和未加引用号的属性键的名称必须是有效的标识符。标识符区分大小写。
标识符的第一个字符是以下之一:
- 任何Unicode字母,包括拉丁字母(如D),希腊字母(如λ)和西里尔字母(如Ä),当然,中文同样可以作为标识符。
- 美元符号(
$
) - 下划线(
_
)
后续字符是:
- 任何合法的第一个角色
- Unicode类别中的任何Unicode数字“十进制数(Nd)”; 这包括欧洲数字,如7和印度数字,如3
- 各种其他Unicode标记和标点符号
合法标识符的示例:
var ε = 0.0001;
var строка = '';
var _tmp;
var $foo2;
尽管这使您能够在JavaScript代码中使用各种人类语言,但我建议您使用英语,同时使用标识符和注释。这确保了最大可能的人群可以理解您的代码,这一点很重要。
以下标识符是保留字 - 它们是语法的一部分,不能用作变量名(包括函数名和参数名):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
以下三个标识符不是保留字,但你应该这么认为:
|
|
|
4 注释
JavaScript有两种注释:单行注释和多行注释。单行注释以行尾开头//并在行尾结束:
x++; // 单行注释
多行注释被分隔/*和*/:
/* 这是
一个
多行注释
*/
5 标签(lable)
JavaScript 语言允许,语句的前面有标签(label),相当于定位符,用于跳转到程序的任意位置,标签的格式如下。
label:
语句
标签可以是任意的标识符,但不能是保留字,语句部分可以是任意语句。标签可与break语句和continue语句配合使用,跳出特定的循环。
top:
for (var i = 0; i < 3; i++){
for (var j = 0; j < 3; j++){
if (i === 1 && j === 1) break top;
console.log('i=' + i + ', j=' + j);
}
}
// i=0, j=0
// i=0, j=1
// i=0, j=2
// i=1, j=0
标签也可用于跳出代码块:
foo: {
console.log(1);
break foo;
console.log('本行不会输出');
}
console.log(2);
// 1
// 2
6 JavaScript的五个基本值和八类值
本节保留Exploring ES5五个基本值说法。
五个基本值
以下是五个基本的值:
- Booleans(布尔值):
true
false
- Numbers(数值):
1023
7.851
- Strings(字符串):
"hello"
'wrold'
- Objects(对象):
{
firstName:'Shrry',
lastName:'Join'
}
- Arrays(数组):
['join','shrry','LiMing']
JavaScript的八类值
除了以上五种值,javascript还包括其他三种值。
以下包括另外三类值:
null(空),undefined(未定义),boolean(布尔值),number(数值),string(字符串)
Object(对象),Array(数组),Function(函数)
源自Scheme,javascript参考其语法(函数编程),函数被视为值且可作为参数传递。
7 变量
定义
变量是对“值”的具名引用。变量就是为“值”起名,然后引用这个名字,就等同于引用这个值。变量的名字就是变量名。
变量的声明和赋值
以下为两个变量赋值:
//声明变量a,b并为其赋值
var a = 1;var b = 2;
//等同于
var a,b;
a = 1;
b = 2;
如果变量只声明而未赋值,则该变量为undefined(未定义):
var b;// undefined
如果变量赋值的时候,忘记写var命令,该条语句也是有效的:
var a = 1;
// 基本等同,但是严格模式'use strict'下会报错
a = 1;
如果一个变量没有声明就直接使用,JavaScript 会报错,告诉你变量未定义:
x
// ReferenceError: x is not defined
值得一提的是,js并没有采用java的静态类型,而是设计为动态类型语言,因此变量的类型没有限值:
var a = 1;
a = 'hello';
变量提升
JavaScript 引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。这造成的结果,就是所有的变量的声明语句,都会被提升到代码的头部,这就叫做变量提升(hoisting)。
console.log(a);
var a = 1;// undefined 而不是 ReferenceError: x is not defined
//执行时为
var a;
console.log(a);
a = 1;
额外的
数据类型(可以理解为变量类型也可以理解为值类型)被分为两类:
- 值类型:null(空),undefined(未定义),boolean(布尔值),number(数值),string(字符串)
- 引用类型:Object(对象),Array(数组),Function(函数)
区别:
- 值类型:
- 占用空间固定,保存在栈中(当一个方法执行时,每个方法都会建立自己的内存栈,在这个方法内定义的变量将会逐个放入这块栈内存里,随着方法的执行结束,这个方法的内存栈也将自然销毁了因此,所有在方法中定义的变量都是放在栈内存中的。栈中存储的是基础变量以及一些对象的引用变量基础变量的值是存储在栈中,而引引变量存储在栈中的是指向堆中的数组或者对象的地址,这就是为何修改引用类型总会影响到其他指向这个地址的引用变量。)
- 保存与复制的是值本身
- 使用的typeof运算检测数据的类型
- 基本类型数据是值类型
- 引用类型:
- 占用空间不固定,保存在堆中(当我们在程序中创建一个对象时,这个对象将被保存到运行时数据区中,以便反复利用(因为对象的创建成本通常较大),这个运行时数据区就是堆内存。堆内存中的对象不会随方法的结束而销毁,即使方法结束后,这个对象还可能被另一个引用变量所引用(方法的参数传递时很常见),则这个对象依然不会被销毁,只有当一个对象没有任何引用变量引用它时,系统的垃圾回收机制才会在核实的时候回收它。)
- 保存与复制的是指向对象的一个指针
- 使用的的instanceof检测数据类型
- 使用new()方法构造出的对象是引用型
熟悉的Java的程序猿一定会觉得很熟悉,是的,JS变量类型机制和Java的的基本一致,这也就能理解为什么说的的JavaScript是一门很像的的Java的脚本语言。
高级
表达式语句
只要javascript需要语句,你也可以编写表达式。这样的语句被称为表达式语句。反过来则不成立,例如if语句不能作为函数的参数。
类似
如果我们查看两个相似的语法类别成员,语句和表达式之间的区别会变得更加清晰。
以下是if语句示例:
var x;
if(y> = 0){
x = y;
} else {
x = -y;
}
表达式有一个模拟条件运算符。以上陈述等同于以下陈述。
var x =(y> = 0?y:-y);
等号和分号之间的代码是一个表达式。括号不是必需的,但如果把它放在parens中,我发现条件运算符更容易阅读。
看起来像语句的表达式
有些表达式看起来像语句。我们将在本节结尾处研究为什么这是一个问题。
对象字面量
下面是一个对象字面量,也就是一个可以生成一个对象值的表达式。
{
foo: bar(3, 5)
}
但是,它也是一个完全合法的语句,其组成部分有:
- 一个代码块:一个由大括号包围的语句序列。
- 一个标签:你可以在任何语句前面放置一个标签.这里的foo就是一个标签。
- 一条语句:表达式语句bar(3, 5)。
{ //区块
foo: //标签
bar(3, 5) //表达式语句
}
函数表达式与函数声明
下面的代码是一个函数表达式:
function(){}
//表达式是一个函数,不像函数声明,函数名不是必须的
您还可以为函数表达式指定名称并将其转换为命名函数表达式:
function foo() { }
如此一来,一个命名的函数表达式从表面上看起来,和一个函数声明并没有什么区别。但它们的效果是不同的:一个函数表达式产生一个值(一个函数).一个函数声明执行一个动作:将一个函数赋值给一个变量. 此外,只有函数表达式可以被立即调用,函数声明不可以.
javascript如何判定看起来像语句的表达式
我们已经看到一些表达式与语句无法区分。这意味着相同的代码工作方式可能不同,具体取决于它是出现在表达式上下文还是语句上下文中。通常情况下,这两种情境明显是分开的。但是,对于表达式语句,存在重叠:在那里,您有表达式出现在语句上下文中。为了防止歧义,JavaScript语法禁止表达式语句以大括号或关键字function开头:
ExpressionStatement : [lookahead ∉ {"{", "function"}] Expression ;
那么如果你想编写一个以上面两个标记中的任何一个开头的表达式语句,你该怎么做?您可以将其放在括号“()”中,这样能确保它仅出现在表达式上下文中。(括号在javascript当中是分组符,里面只能包含表达式,所以解释器会认为这是一个表达式而不是语句)让我们看两个例子:eval和立即调用的函数表达式。
eval
eval在语句上下文中解析其参数。如果希望eval返回一个对象,则必须在对象文字周围加上括号。
eval("{foo:123}")//123
eval("({foo:123})")//{foo:123}
立即调用函数表达式(IIFE)
以下代码是立即调用的函数表达式。
(function(){return "abc"}())// abc
如果省略括号,则会出现语法错误(函数声明不能是匿名的):
function(){return "abc"}()// SyntaxError: function statement requires a name
如果添加名称,则还会出现语法错误(无法立即调用函数声明):
function foo(){return "abc"}()// SyntaxError: syntax error