第02章 基础知识

94 阅读11分钟

一、注释与语句

1、注释

  • 单行注释://
  • 多行注释:/**/
// This is Single-line comments
/*
This is
Multi-line comment  
 */

提示:单行注释不能折行,可以嵌套;多行注释可以折行,不能嵌套;

2、语句

一段脚本就是一系列计算机能够一步一步执行的指令。每一条单独的指令或步骤就被称为一条语句。语句以分号(;)结尾,多个语句可以写在一行内。

var a = 10;                // 这是一条赋值语句
var b = 10; var c = a + b; // 多条语句可以写在一行内;

提示:分号在 JavaScript 中不是必须的,但为了养成良好的编码习惯,建议每一条语句之后都加上分号。

3、输出

1)、控制台输出

var name = 'Petter';

// 1、输出字符串
console.log('Hello, world!');
// "Hello, world!"

// 2、输出变量
console.log(name);
// "Petter"

// 3、输出变量/字符串
console.log('Hello, ' + name + '!');
// "Hello, Petter!"

2)、页面输出

document.write('Hello, world!');

3)、提示框输出

alert('Hello, world!');

4)、确认框

confirm("您确定要退游么?");

5)、输入框

prompt("请输入您的名字");

二、变量

脚本必须暂时地存储一些完成工作所需的信息,可以将这些数据存储在变量中,变量是对 的引用,使用变量等同于引用一个值。每一个变量都有一个变量名。定义变量使用 var 关键字。

var a = 10;

1、声明与赋值

var a;  // 声明变量a
a = 10; // 为变量a赋值

提示:你可以将变量的声明与赋值放在一起,一步到位,如 var a = 10,这种定义变量的方式被称为 字面量定义,即在声明的同时为变量赋值。

如果只是声明变量而不为其赋值,则该变量的值是 undefinedundefined 是一个JavaScript 数据类型,表示未定义。

var a;
a; // undefined

你可以在同一行中声明多个变量。

var a = 10, name = 'Muzili';

tips 1:变量一定先声明,后使用,如果访问一个未定义的变量,程序将报错:

console.log(a);
// Uncaught ReferenceError: a is not defined

tips 2:可以修改变量的值:

var a = 10;
a; // 10

a = 20;
a; // 20

tips 3:JavaScript 允许重复定义变量,如果重复定义,之前的值将会被覆盖,如果只定义不赋值,则新定义的变量无效:

// 定义变量a
var a = 10; 
console.log(a); // 10

// 重复定义变量a
var a;
console.log(a); // 10

var a = 20;
console.log(a); // 20

2、类型推断

JavaScript是一种动态类型的语言,也就是说变量的类型没有限制,可以赋予各种类型的值,变量的类型在赋值之后确定,JavaScript本身存在一种类型推断机制,所谓类型推断,就是根据变量的值确定变量的类型。

3、typeof

通过typeof可以查看变量的数据类型,其返回值类型主要包括:string、boolean、number、undefined、function、object。

三、标识符

标识符是用来识别具体对象的一个名称。最常见的标识符就是 “变量名 ”,以及后面要提到的 “函数名 ”。JavaScript语言的标识符对大小写敏感,所以 aA 是两个不同的标识符。标识符的命名规则如下:。

  • 必须以字母、美元符号($)以及下划线(_)开头,不能以数字开头;
  • 名字可以包含字母、数字、下划线、美元符。注意,在变量中不能使用连字符(-)和点(.)号;
  • 不能使用关键字或保留字来对变量命名。
  • 所有的变量都是大小写敏感的,变量 x 与变量 X 是不一样的;
  • 变量命名必须见名知意,语义化,如创建一个表示年龄的变量,变量名可以取名为 age,再或者要描述一个人的名字你应该取名为name,不能使用拼音或中文命名变量;
  • 如果变量的名字由多个单词组成,则应遵守 驼峰命名 法则,即第一个单词首字母小写,后面单词首字母大写,如一个描述人的姓名的变量,正确的变量命名应该是 personName;

四、关键字与保留字

在上一节中我们提到了两个词语——“关键字”和“保留字”,就是我们在进行变量命名的时候需要避免使用的两类名称。所谓“关键字”,就是JavaScript现在正常使用的一些名称,它们可能是系统变量名,也可能是一个JS内置的方法函数名,还可能是已知宿主环境提供的API。而“保留字”是现在暂时没有使用,但在未来JavaScript可能会使用的名称,这些“保留字”经过JS不断的发展,已经有一些成为了“关键字”。

  • 关键字
breakdoinstanceoftypeofifelse
casevarnewfinallyreturnvoid
continueforswitchwhiledebuggerfunction
thiswithtrycatchthrowdelete
defaultinimplementspackagepublicinterface
privatestaticletprotectedyield
  • 保留字
abstractenumintshortbooleanexport
byteextendslongsupernativesynchronized
classfloatthrowsconstgototransient
volatiledoubleimport

但是需要明白的是JavaScript中的“关键字”和“保留字”也不是一成不变的,它们也会随着这个语言的发展新增或删除(例如“debugger”就是ECMAScript 5中新增的关键字)。但考虑到“向上兼容”,以前提出的这些“关键字”和“保留字”也应该在规范出现更改之后也避免去使用,以免造成程序异常。

五、变量作用域

JavaScript变量分为“局部变量”和“全局变量”。所谓“局部变量”就是指所定义的变量只会在一个限定的范围内生效,通常指在某一个函数内。而通过全局的方法或者其它函数是无法获取该变量的值的。

而“全局变量”,它的值可以被所有的方法或函数获取到。通常将一个变量写在所有函数的外部的变量,就叫做“全局变量”,但是在函数内部,若忘记在变量名前加上var的话,该变量也会成为全局变量,从而不小心被其它函数将值给误改了,所以在函数内部一定要记得在变量名前加上关键字 var 来定义一个变量。

var a = "全局变量";
function print() {
  // a 为全局变量,在任意位置都可以访问
  console.log(a);    
}

function test(y) {
  // 参数 y 也为局部变量
  // x 在函数内部创建,为一个局部变量
  var x = "局部变量"; 
}
console.log(x); // x 为局部变量,此处不能访问x变量,程序会报错
console.log(y); // y 为局部变量,此处不能访问y变量,程序会报错    

变量作用域表示变量起作用的范围,全局变量的作用域为整个文件内部,称之为全局作用域。而局部变量的作用域通常限于函数内部,称之为函数作用域

// 立即执行函数
(function () {
    var str = 'Hello, World!';
    console.log(str);
})();

六、运算符与表达式

1、 基本运算符

基本运算符主要用于一些数值操作:

  • +:加法运算符,如 a + b
  • -:减法运算符,如 a - b
  • *:乘法运算符,如 a * b
  • /:除法运算符,如 a / b
  • %:模运算(取余数),如 a % b
  • ++:自增运算符(自身+1)
  • --:自减运算符(自身-1)

提示:自增与自减运算符都是让自身 +1-1,在使用上无差别,这里以自增运算符为例。

1)、无论 ++ 运算符在变量前还是在变量后,变量自身都会 +1

var a = 10;
a++; // 11
++a; // 12

2)、++ 在前,先自增、再赋值;++ 在后,先赋值,再自增

var a = 10;
var x = ++a; // x = 11, a = 11

var a = 10;
var x = a++; // x = 10, a = 11

2、 赋值运算符

赋值运算符是为JavaScript中的变量赋值,即将该运算符右方计算出的值赋予左侧的变量。

  • =:赋值运算符,如 x = 10; ,将 10 赋值给变量 x

3、复合运算符

  • +=:变量与值相加,如 x += y; 相当于 x = x + y
  • -=:变量与值相加,如 x -= y; 相当于 x = x - y
  • *=:变量与值相加,如 x *= y; 相当于 x = x * y
  • /=:变量与值相加,如 x /= y; 相当于 x = x / y
  • %=:变量与值相加,如 x %= y; 相当于 x = x % y

4、关系运算符

关系运算符描述两个变量的关系,其返回值类型为布尔类型(boolean),即 truefalse

  • ==:判断两个变量是否相等,如 'China' == 'China',返回 true
  • !=:判断两个变量是否不相等
  • >:判断等号左边的变量是否大于等号右边的变量,如 20 > 10,返回 true
  • <:判断等号左边的变量是否小于等号右边的变量,如 20 < 10 ,返回 false
  • >=:判断等号左边的变量是否大于等于等号右边的变量,如 20 >= 10,返回 true
  • <=:判断等号左边的变量是否小于等于等号右边的变量,如 20 <= 10,返回 false
  • ===:恒等于,要求不仅数据类型要一致,值也要一致,如 1 === '1',返回 false
  • !==:不恒等于,只要类型或值不一样,结果为true,如 1 !== '1',返回 true

5、逻辑运算符

逻辑运算符是JavaScript用于判断几条语句成立情况的一种运算,该运算符的返回值类型为布尔类型。

  • 逻辑与:&& ,同时为真才为真,如 (1 > 2) && (2 > 3),返回 false
  • 逻辑或:|| ,同时为假才为假,如 (1 > 2) || (2 > 1),返回 true
  • 逻辑非: ! ,取反,如 !(1 > 2),返回 true

6、三元运算符

三元运算用于条件判断,根据判断的结果执行不同的语句,其语法形式为:a ? b : c。如果a表达式的条件为真,则执行b语句,否则执行c语句。我们来看一个示例:

var isLogin = true; // 定义变量’isLogin‘用于记录登录状态
isLogin ? console.log('已登录!') : console.log('未登录!');

上述代码使用三目运算符根据登录状态执行不同的语句,代码中的 console.log() 函数用于向控制台输出信息。由于定义的变量值为true,因此上述代码执行后会在控制台输出:“您已登录!”

7、优先级

优先级运算符说明结合性
1[].()字段访问、数组索引、函数调用和表达式分组从左向右
2++ -- -~!delete new typeof void一元运算符、返回数据类型、对象创建、未定 义的值从右向左
3*、/、%相乘、相除、求余数从左向右
4+、-相加、相减、字符串串联从左向右
5<<、>>、>>>左位移、右位移、无符号右移从左向右
6<、<=、>、>=、instanceof小于、小于或等于、大于、大于或等于、是否 为特定类的实例从左向右
7==、!=、===、!==相等、不相等、全等,不全等从左向右
8&按位“与”从左向右
9按位“异或”从左向右
10|按位“或”从左向右
11&&短路与(逻辑“与”)从左向右
12||短路或(逻辑“或”)从左向右
13?:条件运算符从右向左
14=、+=、-=、*=、/=、%=、&=、|=、^=、<、<=、>、>=、>>=混合赋值运算符从右向左
15,多个计算按优先级计算,然后从右向左

七、基本数据类型(概述)

  • 原始数据类型:Number,String,Boolean,BigInt,Symbols,Null,Undefined

  • 对象数据类型:Object,Function,Date,Array,Maps,Sets,JSON

# 比较 null 与 undefined:

  • null 是一个表示"空"的对象,转为数值时为0;

  • undefined 是一个表示"空"的原始值,转为数值时为NaN;

当声明的变量还未被初始化时,变量的默认值为 undefined。 null 用来表示尚未存在的对象。

undefined表示"缺少值",就是此处应该有一个值,但是还没有定义。典型用法是:

  1. 变量被声明了,但没有赋值时,就等于undefined。

  2. 调用函数时,应该提供的参数没有提供,该参数等于undefined。

  3. 对象没有赋值的属性,该属性的值为undefined。

  4. 函数没有返回值时,默认返回undefined。

null表示"没有对象",即该处不应该有值。典型用法是:

  1. 作为函数的参数,表示该函数的参数不是对象。

  2. 作为对象原型链的终点。

八、类型转换

1、强制类型转换

数值类型:Number()、parseInt()、parseFloat()

字符串类型:String()

布尔值类型:Boolean() => undefined、0、+0、-0、NaN、""、null 转换为false

提示:

Number():整体转换,只要存在非数字字符均返回NaN

parseInt():转换整数,不能转换科学计数法,从左往右依次转换,直到遇到非数字字符为止

parseFloat:转换浮点数,可以转换科学计数法,从左往右依次转换,直到遇到非数字字符为止

代码示例:

Number('a'); // NaN
Number('1'); // 1

parseInt('1a'); // 1
parseInt('a');  // NaN

2、自动类型转换

数值类型:10 - "2" 等,示例中,字符串 "2" 会被转换成数值 2 再进行运算,所以结果为 8

字符串类型:10 + "2" 等,示例中,数值 10 会被转换成字符串 "10",然后再进行拼接,所以结果为 "102"

布尔值类型:if、==、===、&&、||、!等

3、类型转换优化

提示:显式转换比隐式转换性能更好;

在一般转换中,还可以通过如下示例提升性能。

var n = "3.14";
"" + n; // -> string
~~n;    // -> integer
1 * n;  // -> float
!!n;    // -> boolean
[n];    // -> array
+n;     // -> number