首页 > 技术文章 > 基本概念

jonas-von 2018-11-13 16:50 原文

基本概念

  任何语言的核心都必然会描述这门语言最接班的工作原理。而描述的内容通常都要涉及这门语言的语法,操作符,数据类型,内置功能等等。接下来就让我们由浅到深的认识 JavaScript。

(一)基本语法

  ECMAScript 的语法大量借鉴了程序语言鼻祖 C 语言的语法,但是在某些程度上要比 C 或类C语言(如Java)要简洁和灵活,这或许是弱类型的动态的脚本语言的共性吧。言归正传,谈到语法不得不说的一点就是标识符,标识符就是指变量、函数、属性以及函数参数的名字,然而 ES 规定了以下的规则去定义标识符,一旦不符合规则就会抛出错误。

① 可以包含字母、数字、下划线和$,但是不能以数字开头,建议使用驼峰命名法进行命名。

② 严格区分大小写,意思就是说,变量 test 和 TEST 不是同一个变量。

③ 不能用关键字和保留字来命名,关键字就是 ES 定义的一些特殊字符,用于实现某些功能的字符,比如说,var 是一个关键字,它用于声明变量,function 是一个关键字,用于声明函数;而保留字则是 ES 为了未来的发展先占用的一些字符。

④ 忽略多个空格和换行,多个空格和换行只会被翻译为一个空格。

⑤ 一条语句通过分号;结尾,当然这不是必须的,如今的一些框架更是有点“嫌弃”分号的意思,但是在原生的 JS 下,有时候如果不写分号就会报错,例如,函数自调用,如果后面还跟着语句,则会抛出错误。

⑥ 严格模式,在一个作用域的顶部都可以通过字符串 “use strict”来告诉解释引擎这段代码需要在严格模式下执行。

  严格模式是 ES5 提出的一个模式,在这种模式下的代码将会被规范得更加严格,这个规范的内容也比较多,当然大部分都是我们一般情况下都能避免的(意思就是根本不会那么去写),所以在此就说一个容易犯错的:在严格模式下,所有变量必须先定义后使用,在标准模式下,如果一个变量没有通过关键字(var,const 或者 let)来定义,则会被认为是 window 对象下的属性,然而这事在严格模式下就不好使了,如果一个变量没有通过关键字定义就使用了就会抛出错误。如果你对这个模式感兴趣的,可以跳转到 W3schools 去看看(不是国内的这个,需要梯子)。

 

(二)数据类型

  每种开发语言都有自己的数据类型,JavaScript 也不例外,它一共有 7 种数据类型,分别是 String、Number、Boolean、Undefined、Null、Object 以及 ES6新提出的 Symbol。其中,前面 5 种是基本数据类型,用于描述简单的数据;Object也被称为引用数据类型(也有复合数据类型,复杂数据类型的说法);Symbol 类型是区别于基本类型和引用类型的一种特殊类型,详情在后面再作介绍。

① String 类型

  String 类型用于表示零个或多个16位Unicode字符组成的字符序列,被称为字符串。字符串可以使用单引号或双引号引起来,比如:

let name = 'jonas'
let gender = "male"

这里还需要注意的是String可以表示零个字符('' 或 "")的情况,这也被称为空串,它是字符串特殊的代表;除此以外,还有一些‘特殊份子’,他们表示非打印字符,用于告诉解释器如何解释这个字符串,他们被称为转义字符:

他们可以在字符串中的任意位置出现表示特定的意思。

 

② Number 类型

  Number 类型用于表示所有与数值相关的值,包括我们日常生活中的整数,小数以及开发用到的8进制数,16进制数等等。最基本的十进制整数,小数直接表示即可;如果需要表示8进制,则需要在收尾加上0,后面的数字是8进制字序(0 - 7);同样的,如果需要表示16进制,则需要在前面加上 0x ,后面为 0-9 以及 A-F,字母大小写均可。另外,在进行算术运算时,统一都会转化为十进制。关于算术运算,JavaScript 对于小数的加减法存在一定的问题,比如说:

const a = 9.9
const b = 8.8
const c = (a * 100000 + b * 100000) / 100000
const d = a + b
console.log('c = '+c,'d = '+d)

你觉得 c 和 d 相等吗? 或者说,正常情况下应该相等吧,但是很遗憾:

所以说,如果要进行精确运算,你最好还是别用 JS 了。

  Number 类型还有几个特殊的代表,一个是无穷,因为受限于内存,ES 不可能保存一个很大很大很大的数,一旦超过 Number.MAX_VALUE (大多数浏览器会解释为:1.7976931348623157e+308),则会解释为 Infinity,如果是负数,则解释为 -Infinity;除了最大值,ES 还定义了一个最小值 Number.MIN_VALUE,这个是最小的正数,值为 5e-324;除此以外,还有一个特殊值 NaN ,全称 not a number ,表示该值不是一个数值。

 

③ Boolean 类型

  布尔类型,只有两个值,true 和 false 。

 

④ Undefined 类型

  只有一个值:undefined,在以下的情况中存在:

1、未赋值的变量

2、没有对应实参的形参

3、读取对象中不存在的属性

以上3种情况都会返回 undefined

 

⑤ Null 类型

  只有一个值:null,表示一个空对象指针,可用于处理垃圾对象,将一个对象指向为 null,则该对象会由垃圾回收机制(不会立马回收,后面章节介绍)进行回收从而释放内存。

 

  以上五种数据类型统称为基本数据类型,然而在开发过程中,这几种类型偶尔也会面临一个类型之间相互转换的问题,这里说的相互转换只包括基本类型转为 String 、Number 或者 Boolean,因为转化为 undefined 或 null 没有太大意义,转化的方式有两种,一种是强制类型转换,另外一种是隐式类型转换(后者比较常用):

  所谓强制类型转换就是利用 String()、Number() 和 Boolean() 三个方法进行的转换。

  1、将其他类型转换为 String 类型:

    强制类型转换:String( ) 或者 toString( ) , 注意:toString()是Object对象的原型对象的方法,null和undefined类型的数据不能通过toString这个方法转为字符串。

    隐式类型转换:将空串与其他类型做加法运算即可,空串的魅力~~  。

  2、将其他类型转换为 Number 类型:

    强制类型转换:Number( ) 

    隐式类型转换:使用一元运算符 + ,比如:const a = +'1' ,最终 a 变量保存的就是数值 1,Number类型。

  3、将其他类型转换为 Boolean 类型:

    强制类型转换:Boolean( )

    隐式类型转换:二次取反 !!

  还有Object 和 Symbol 两种类型在后面章节再讨论。

 

(三)操作符

① 算术运算符

  比较简单的就不再阐述了,比如说 加(+)、减(-)、乘(*)、除(/),在此主要说一些可能不太常见的,例如 % 表示取模或者说是取余数;** 是ES7的语法,表示乘方,比如 2的3次方可以表示为 2**3;

② 布尔操作符

  逻辑或 ||  ,逻辑与 &&  , 逻辑非 !

  这里需要注意的是,前面两个是二元运算符,逻辑非是一元运算符,前面两者运算的返回值不一定是布尔值,例如:1 && 2 返回的结果是 2,而不是 true

③ 关系运算符

  也就是小学学的大于(>),小于(<),大于或等于(>=),小于或等于(<=),需要注意的是这里的返回值是一个布尔值。

④ 相等运算符

  双等(==)、全等(===)、不等(!=)以及不全等(!==)

  双等与全等的区别是,双等会自动做类型转换,然而全等不会,全等不仅仅比较两个值是否相等,而且还会比较他们的数据类型是否一致,多用全等。

⑤ 三元运算符

  条件表达式 ? 表达式1 : 表达式2;如果条件表达式为true, 则执行表达式1,否则执行表达式2。可嵌套多层使用。

 

(四)语句

  if-else语句:

if(条件表达式){
  ...  
}else if(条件表达式){
  ...  
}
(可多个else if)
else{
  ...
}

只执行第一个条件表达式为true的语句,执行完毕直接跳出,不会再执行该语句里面的其他代码块。

  switch-case语句:

switch(n){
  case a:
      ...
  case b:
      ...
  default:
      ...
} 

需要注意的是,switch-case语句会做全等比较,一旦符合条件的就会进入执行,并且从此一发不可收拾的往下执行所有语句,当然前提是没有通过break跳出,如果遇到break则跳出该语句。default 相当于 else ,如果没有匹配的结果,则进入 defalut 执行。

  for循环:

for(初始化表达式;条件判断语句;迭代条件){
    循环体
}

 

  while循环:

while(条件判断语句){
    循环体
}

 

  do...while循环:

do{
    循环体
}while(条件判断语句)

推荐阅读