JavaScript 数据类型

文章目录

    • 六种数据类型
    • 数值
    • 字符串
    • 对象
    • 函数
      • 函数的声明
      • 函数名的提升
      • 函数作用域
      • 函数参数
      • 立即调用的函数表达式
      • eval
    • 数组

原文来自阮一峰的博客

六种数据类型

六种数据类型:

  • 数值(number)
  • 字符串(string)
  • 布尔值(boolean)
  • undefined
  • null
  • 对象(object)

通常,数值、字符串、布尔值这三种类型,合称为原始类型(primitive type)的值,即它们是最基本的数据类型,不能再细分了。

对象则称为合成类型(complex type)的值,因为一个对象往往是多个原始类型的值的合成,可以看作是一个存放各种值的容器。

至于 undefinednull,一般将它们看成两个特殊值。

对象是最复杂的数据类型,又可以分成三个子类型:

  • 狭义的对象(object)
  • 数组(array)
  • 函数(function)

后面说的对象一般指狭义的对象。

数值

JavaScript 内部,所有数字都是以 64 位浮点数形式储存,即使整数也是如此。所以,1 与 1.0 是相同的,是同一个数。

JavaScript 语言的底层根本没有整数,所有数字都是小数( 64 位浮点数)。容易造成混淆的是,某些运算只有整数才能完成,此时 JavaScript 会自动把 64 位浮点数,转成 32 位整数,然后再进行运算。

根据国际标准 IEEE 754,JavaScript 浮点数的 64 个二进制位,从最左边开始,是这样组成的。

  • 第1位符号位,0表示正数,1表示负数
  • 第2位到第12位(共11位):指数部分
  • 第13位到第64位(共52位):小数部分(即有效数字)

JavaScript 的64位浮点数之中,有一个二进制位是符号位。这意味着,任何一个数都有一个对应的负值,就连 0 也不例外。

JavaScript 内部实际上存在 2 个 0 :一个是 +0,一个是 -0,区别就是64位浮点数表示法的符号位不同。

NaN 是 JavaScript 的特殊值,表示「非数字」(Not a Number),主要出现在将字符串解析成数字出错的场合。

Infinity 表示「无穷」,用来表示两种场景。一种是一个正的数值太大,或一个负的数值太小,无法表示;另一种是非 0 数值除以 0 ,得到Infinity。

与数值相关的全局方法:

  • parseInt() 用于将字符串转为整数
  • parseFloat() 用于将一个字符串转为浮点数
  • isNaN() 用来判断一个值是否为 NaN
  • isFinite() 返回一个布尔值,表示某个值是否为正常的数值

字符串

字符串就是零个或多个排在一起的字符,放在单引号或双引号之中。

字符串可以被视为字符数组,因此可以使用数组的方括号运算符,用来返回某个位置的字符(位置编号从 0 开始)。

JavaScript 使用 Unicode 字符集。JavaScript 引擎内部,所有字符都用 Unicode 表示。JavaScript 不仅以 Unicode 储存字符,还允许直接在程序中使用 Unicode 码点表示字符,即将字符写成 \uxxxx 的形式,其中 xxxx 代表该字符的 Unicode 码点。

与字符串相关的属性和方法:

  • length 属性返回字符串的长度
  • btoa() 任意值转为 Base64 编码
  • atob() Base64 编码转为原来的值

对象

对象就是一组「键值对」(key-value)的集合,是一种无序的复合数据集合。

对象的所有键名都是字符串(ES6 又引入了 Symbol 值也可以作为键名),所以加不加引号都可以。如果键名是数值,会被自动转为字符串。

对象的每一个键名又称为「属性」(property),它的「键值」可以是任何数据类型。如果一个属性的值为函数,通常把这个属性称为「方法」,它可以像函数那样调用。

对象采用大括号表示,这导致了一个问题:如果行首是一个大括号,它到底是表达式还是语句?为了避免这种歧义,JavaScript 引擎的做法是,如果遇到这种情况,无法确定是对象还是代码块,一律解释为代码块。

如果要解释为对象,最好在大括号前加上圆括号。因为圆括号的里面,只能是表达式,所以确保大括号只能解释为对象。

与对象相关的全局方法和语法糖:

  • Object.keys() 查看一个对象本身的所有属性
  • in 运算符用于检查对象是否包含某个属性
  • for...in 循环用来遍历一个对象的全部属性
  • with 语句作用是操作同一个对象的多个属性时,提供一些书写的方便

函数

函数的声明

JavaScript 中声明函数的方法:

  • function 命令声明的代码区块,就是一个函数。
  • 一个匿名函数赋值给变量,这个匿名函数又称函数表达式(Function Expression)

还有通过 Function 构造函数声明函数,不直观,几乎没人用。

如果同一个函数被多次声明,后面的声明就会覆盖前面的声明。

函数名的提升

JavaScript 语言将函数看作一种值,与其它值(数值、字符串、布尔值等等)地位相同。

JavaScript 引擎将函数名视同变量名,所以采用 function 命令声明函数时,整个函数会像变量声明一样,被提升到代码头部。

函数作用域

作用域(scope)指的是变量存在的范围。在 ES5 的规范中,JavaScript 只有两种作用域:

  • 全局作用域,变量在整个程序中一直存在,所有地方都可以读取
  • 函数作用域,变量只在函数内部存在

ES6 又新增了块级作用域。

对于顶层函数来说,函数外部声明的变量就是全局变量(global variable),它可以在函数内部读取。

在函数内部定义的变量,外部无法读取,称为局部变量(local variable)。

与全局作用域一样,函数作用域内部也会产生「变量提升」现象。var命令声明的变量,不管在什么位置,变量声明都会被提升到函数体的头部。

函数本身也是一个值,也有自己的作用域。它的作用域与变量一样,就是其声明时所在的作用域,与其运行时所在的作用域无关。

函数参数

函数参数不是必需的,JavaScript 允许省略参数。

函数参数如果是原始类型的值(数值、字符串、布尔值),传递方式是传值传递(passes by value)。

如果函数参数是复合类型的值(数组、对象、其他函数),传递方式是传址传递(pass by reference)。

由于 JavaScript 允许函数有不定数目的参数,所以需要一种机制,可以在函数体内部读取所有参数。arguments 对象包含了函数运行时的所有参数,arguments[0] 就是第一个参数,arguments[1] 就是第二个参数,以此类推。这个对象只有在函数体内部,才可以使用。

JavaScript 规定,如果 function 关键字出现在行首,一律解释成语句。因此,引擎看到行首是 function 关键字之后,认为这一段都是函数的定义,不应该以圆括号结尾,所以就报错了。

立即调用的函数表达式

函数定义后立即调用的解决方法,就是不要让 function 出现在行首,让引擎将其理解成一个表达式。最简单的处理,就是将其放在一个圆括号里面。这就叫做「立即调用的函数表达式」(Immediately-Invoked Function Expression),简称 IIFE。

eval

eval 命令接受一个字符串作为参数,并将这个字符串当作语句执行。

eval 的本质是在当前作用域之中,注入代码。由于安全风险和不利于 JavaScript 引擎优化执行速度,一般不推荐使用。

函数的全局属性和方法:

  • name 属性返回函数名字
  • length 属性返回函数预期传入的参数个数
  • toString() 方法返回一个字符串,内容是函数的源码

数组

数组(array)是按次序排列的一组值。每个值的位置都有编号(从 0 开始),整个数组用方括号表示。

数组属于一种特殊的对象。typeof 运算符会返回数组的类型是 object

数组的特殊性体现在,它的键名是按次序排列的一组整数(0,1,2…)。

JavaScript 语言规定,对象的键名一律为字符串,所以,数组的键名其实也是字符串。之所以可以用数值读取,是因为非字符串的键名会被转为字符串。

数组的全局属性和方法:

  • length 属性,返回数组的成员数量
  • in 运算符,检查某个键名是否存在
  • for...in 循环和数组的遍历

阮一峰 JavaScript 教程
阮一峰 ES6 教程

你可能感兴趣的:(javascript,开发语言,ecmascript)