转行学前端的第 26 天 : 了解 ECMAScript 七种基础数据类型 (上篇)

811 阅读18分钟

我是小又又,住在武汉,做了两年新媒体,准备用 6 个月时间转行前端。

今日学习目标


昨天基于一些页面搜索,学习了《JavaScirpt 高级程序设计》(第三版)  第 3 章节中的 ES 基础概念中语法和变量,今天主要是基于搜索来学习第 3 章节中的 ES 基础概念中基础数据类型,又是适合学习的一天,加油,小又又!!!!

原本准备用一篇文章进行发布的,但是,发布一直提示 Request Entity Too Large,就分两篇发布了~~~

今日学习概要在第一篇,总结在第二篇~~~~


今日学习概要


数据类型数据结构中的定义是一个集合以及定义在这个值集上的一组操作

变量是用来存储值所在处,它们有名字数据类型变量数据类型决定了如何将代表这些位存储到计算机的内存中。在声明变量时也可指定它的数据类型。所有变量都具有数据类型,以决定能够存储哪种数据

最新的 ECMAScript 标准定义了8种数据类型

  • 七种基本数据类型:
    • undefined ,和 null 一样是一个特殊的关键字,undefined 表示变量未定义时的属性。
    • null , 一个表明 null 值的特殊关键字。 JavaScript 是大小写敏感的,因此 nullNullNULL或变体完全不同。
    • 布尔值(Boolean),有2个值分别是:truefalse.
    • 数字(Number),整数或浮点数,例如: 42 或者 3.14159
    • 任意精度的整数 (BigInt) ,可以安全地存储和操作大整数,甚至可以超过数字的安全整数限制。
    • 字符串(String),字符串是一串表示文本值的字符序列,例如:"Howdy" 。
    • 代表(Symbol) ( 在 ECMAScript 6 中新添加的类型).。一种实例是唯一且不可改变的数据类型。
  • 以及对象(Object)。


虽然这些数据类型相对来说比较少,但是通过他们,可以在程序中开发有用的功能。对象(Objects)和函数(functions)是这门语言的另外两个基本元素。你可以把对象当作存放值的一个命名容器,然后将函数当作你的程序能够执行的步骤。


undefined

what


当声明的变量未初始化时,该变量的默认值是undefined,即该值的数据类型和数据内容都是undefined

function test(t) {
  if (t === undefined) {
     return 'Undefined value!';
  }
  return t;
}

let x;

console.log(typeof x);
console.log(test(x));


undefined也是_全局对象_的一个属性。也就是说,它是全局作用域的一个变量。undefined的最初值就是原始数据类型[undefined](https://developer.mozilla.org/zh-CN/docs/Glossary/undefined)


attribute


在现代浏览器(JavaScript 1.8.5/Firefox 4+),自ECMAscript5标准以来undefined是一个不能被配置(non-configurable),不能被重写(non-writable)的属性。

即便事实并非如此,也要避免去重写它~~~

undefined 属性的属性特性:
writable false
enumerable false
configurable false

example

严格相等和undefined



你可以使用undefined和严格相等或不相等操作符来决定一个变量是否拥有值。在下面的代码中,变量x是未定义的,if 语句的求值结果将是true
var x;
if (x === undefined) {
// 执行这些语句
} else {
// 这些语句不会被执行
}


注意:这里是必须使用严格相等操作符(===)而不是标准相等操作符(==),因为 x == undefined 会检查x是不是null,但是严格相等不会检查(有点饶人,其实 === 会严格判断双方的类型、值等是否相等)。

null不等同于undefined。移步比较操作符查看详情。


Typeof 操作符和undefined

或者,可以使用typeof

var x;
if(typeof x === 'undefined') {
    // 执行这些语句
}


使用 typeof的原因是它不会在一个变量没有被声明的时候抛出一个错误。

// 这里没有声明y
if(typeof y === 'undefined') {       // 没有错误,执行结果为true
   console.log("y is " + typeof y )  // y is undefined
}
if(y === undefined) {                // ReferenceError: y is not defined
}


但是,技术方面看来这样的使用方法应该被避免。

JavaScript是一个静态作用域语言,所以,一个变量是否被声明可以通过看它是否在一个封闭的上下文中被声明。唯一的例外是全局作用域,但是全局作用域是被绑定在全局对象上的,所以要检查一个变量是否在全局上下文中存在可以通过检查全局对象上是否存在这个属性(比如使用in操作符)。

if ('x' in window) {
  // 只有x被全局性的定义 才会这行这些语句
}

Void操作符和undefined

void 操作符是第三种可以替代的方法。

var x;
if(x === void 0) {
    // 执行这些语句
}
// 没有声明y
if(y === void 0) {
    // 抛出一个RenferenceError错误(与`typeof`相比)
}

tip

但是,值   undefined 并不同于未定义的值typeof 运算符会将未定义未声明的变量数据类型都打印为undefined

    var oTemp;
    console.log(typeof oTemp);  //输出  undefined 
    console.log(typeof oTemp2);  //输出  undefined




请注意,对于未声明的变量使用除 typeof 之外的其他运算符的话,会引起错误,因为其他运算符只能用于已声明的变量上。


例如,下面的代码将引发错误:

    var oTemp;
    console.log(oTemp2 == undefined);




当函数无明确返回值时,返回的也是值 undefined,如下所示:

    function testFunc() {
    }

    console.log(testFunc() == undefined);  //输出 "true"



Null

what


值 null 特指对象的值未设置。它是 JavaScript 基本类型 之一,在布尔运算中被认为是falsy

它只有一个专用值 null,即它的字面量

值 null 是一个字面量,不像 undefined,它不是全局对象的一个属性。null 是表示缺少的标识,指示变量未指向任何对象。

把 null 作为尚未创建的对象,也许更好理解。在 API 中,null 常在返回类型应是一个对象,但没有关联的值的地方使用。

function getVowels(str) {
  const m = str.match(/[aeiou]/gi);
  if (m === null) {
    return 0;
  }
  return m.length;
}

console.log(getVowels('sky'));
// expected output: 0





example


也可以通过将变量的值设置为 null 来清空变量。

    var temp ="";
    console.log(typeof temp);//string
    temp=null;
    console.log(typeof temp);//object

tip

undefined实际上是从值null派生来的,因此ECMAScript在执行类型转换匹配的前提下,它们定义为相等的。

    console.log(null == undefined);  //输出 "true"


尽管这个情况下,两个值相等,但它们的含义不同~~~~~

  • undefined 是声明了变量但未对其初始化时赋予该变量的值
  • null 则用于表示尚未存在的对象(在讨论 typeof 运算符时,简单地介绍过这一点)。


但是在[全等(===)操作符](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators) 下,两者并不相等~~~~
typeof null        // "object" (因为一些以前的原因而不是'null')
typeof undefined   // "undefined"
null === undefined // false
null  == undefined // true
null === null // true
null == null // true
!null //true
isNaN(1 + null) // false
isNaN(1 + undefined) // true

如果函数或方法要返回的是对象,那么找不到该对象时,返回的通常是 null

    console.log(typeof null)// "object"
    console.log(typeof {})// "object"


`typeof` 运算符对于 `null` 值会返回 `Object`,这实际上是 `JavaScript` 最初实现中的一个错误,然后被 `ECMAScript` 沿用了。现在,`null` 被认为是`对象的占位符`,从而解释了这一矛盾,但从技术上来说,它仍然是`原始值`。

Boolean

what


Boolean 类型是 ECMAScript最常用的类型之一。它有两个值 truefalse (即两个 Boolean 字面量)。
即使 false 不等于 00 也可以在必要时被转换成 false,这样在 Boolean 语句中使用两者都是安全的。

    var temp = true;
    console.log(typeof temp);//boolean
    temp = !0;
    console.log(typeof temp)//boolean
    console.log(temp)//true

attribute


Boolean.prototype 属性的属性特性:
writable false
enumerable false
configurable false

grammar

布尔字面量


直接输入的(而不是从另一个变量访问的)任何数字都被看做 Number 类型的字面量。例如,下面的代码声明了存放整数值的变量,它的值由字面量 86 定义:

    var temp = 86;
    console.log(typeof temp);//number
    console.log(temp);//86

Boolean 对象

  • 创建 Boolean 对象的语法
new Boolean([value])
  • 参数


 可选,用来初始化 Boolean 对象的值。

  • 返回值


如果第一个参数不是布尔值,则会将其转换为布尔值。如果省略该参数,或者其值为 0-0nullfalseNaNundefined、或者空字符串(""),则生成的 Boolean 对象的值为 false

如果传入的参数是 DOM 对象  document.all,也会生成值为 falseBoolean 对象。任何其他的值,包括值为 "false" 的字符串和任何对象,都会创建一个值为 trueBoolean 对象。

注意不要将基本类型中的布尔值 truefalse 与值为 truefalseBoolean 对象弄混了。

  • Boolean 对象属性
属性 描述
constructor 返回创建了实例原型的函数。默认为Boolean函数。
length length 属性,值为 1。

example

创建值为 falseBoolean 对象


var bNoParam = new Boolean();
var bZero = new Boolean(0);
var bNull = new Boolean(null);
var bEmptyString = new Boolean('');
var bfalse = new Boolean(false);

创建值为 true 的  Boolean 对象


var btrue = new Boolean(true);
var btrueString = new Boolean('true');
var bfalseString = new Boolean('false');
var bSuLin = new Boolean('Su Lin');
var bArrayProto = new Boolean([]);
var bObjProto = new Boolean({});

tip

任何不是 undefinednull 的对象,包括值为 falseBoolean 对象,直接用于条件语句时都会被当做 true 来对待。


例如,下面 if 语句中的条件为真:

var x = new Boolean(false);
if (x) {
  // 这里的代码会被执行
}
基本类型的布尔值不受此规则影响。例如下面的 if 语句的条件为假:
var x = false;
if (x) {
  // 这里的代码不会执行
}

不要用创建 Boolean 对象的方式将一个非布尔值转化成布尔值,直接将 Boolean 当做转换函数来使用即可,或者使用双重非(!!)运算符

var x = Boolean(expression);     // 推荐
var x = !!(expression);          // 推荐
var x = new Boolean(expression); // 不太好

对于任何对象,即使是值为 falseBoolean 对象,当将其传给 Boolean 函数时,生成的 Boolean 对象的值都是 true

var myFalse = new Boolean(false);   // false
var g = new Boolean(myFalse);       // true
var myString = new String("Hello");
var s = new Boolean(myString);      // true


最后,不要在应该使用基本类型布尔值的地方使用 Boolean 对象。


Number

what


 JavaScript 的 Number 对象是经过封装的能让你处理数字值的对象。

Number 对象由 Number() 构造器创建。

JavaScript 的Number类型为双精度IEEE 754 64位浮点类型。但是既可以表示 32 位整数,还可以表示 64 位浮点数

最近出了stage3BigInt 任意精度数字类型,已经进入stage3规范。


attribute


Number.prototype 属性的属性特性:
writable false
enumerable false
configurable false

grammar

数字字面量


直接输入的(而不是从另一个变量访问的)任何数字都被看做 Number 类型的字面量。例如,下面的代码声明了存放整数值的变量,它的值由字面量 86 定义:

    var temp = 86;
    console.log(typeof temp);//number
    console.log(temp);//86

八进制数和十六进制数


整数也可以被表示为八进制(以 8 为底)或十六进制(以 16 为底)的字面量。尽管所有整数都可以表示为八进制或十六进制的字面量,但所有数学运算返回的都是十进制结果。

八进制字面量首数字必须是 0,其后的数字可以是任何八进制数字(0-7),如下面的代码所示:

    var temp = 070;
    console.log(typeof temp);//number
    console.log(temp);//打印出来是显示十进制的56


要创建十六进制字面量首位数字必须为0,后面接字母 x(不分大小写),然后是任意的十六进制数字(0 到 9 和 A 到 F)。这些字母可以是大写的,也可以是小写的。例如:

    var temp = 0x1f;
    console.log(temp);//打印出来是显示十进制的31
    temp = 0xAB;
    console.log(temp);//打印出来是显示十进制的171

浮点数


要定义浮点值,必须包括小数点和小数点后的一位数字(例如,用 1.0 而不是 1)。这被看作浮点数字面量。例如:

    var temp = 5.0;
    console.log(temp);//显示整数  5
    temp = 5.5;
    console.log(temp);//显示浮点数  5.5
    temp = 5.5+"";
    console.log(typeof temp);//string


对于浮点字面量的有趣之处在于,用它进行计算前,真正存储的是字符串

科学计数法


对于非常大非常小的数,可以用科学计数法表示浮点数,可以把一个数表示为数字(包括十进制数字)加 e(或 E),后面加乘以 10 的倍数。对于极小值的浮点可以通过toFixed(number)将指定数字截取小数点后number位,或者是利用Math.round()方法将一个数字舍入为最接近的整数,但是对于正整数,需要使用toPrecision(number)将整个数字截取指定number长度。

    var temp = 5.618e7;
    console.log(temp);
    //显示整数  56180000  5.618 x 10^7
    temp = 8e-17;
    console.log(temp);//8e-17

    temp = 0.000000000000000000000000000001245893576484897879;
    console.log(temp);//1.2458935764848978e-30
    //请注意只显示小数点位后十六位,之后会省略
    console.log(temp.toFixed(2));//0.00
    console.log(temp.toPrecision(2));//1.2e-30
    console.log(Math.round(temp));//0

    temp = 124589357648489787900000000000000000000000000000;
    console.log(temp);//1.245893576484898e+47
    //请注意只显示小数点位后十五位,之后会省略
    console.log(temp.toFixed(2));//1.245893576484898e+47
    console.log(temp.toPrecision(2));//1.2e+47
    console.log(Math.round(temp));//1.245893576484898e+47


ECMAScript 默认把具有6 个或 6 个以上前导 0 的浮点数转换成科学计数法。也可用 基于IEEE 754标准的64 位形式存储浮点值,这意味着十进制值最多可以有 17十进制位17 位之后的值将被裁去,从而造成一些小的数学误差

IEEE 754 标准是IEEE二进位浮点数算术标准(IEEE Standard for Floating-Point Arithmetic)的标准编号[1]  ,等同于国际标准ISO/IEC/IEEE 60559。该标准由美国电气电子工程师学会(IEEE)计算机学会旗下的微处理器标准委员会(Microprocessor Standards Committee, MSC)发布。

这个标准定义了表示浮点数的格式(包括负零-0)与反常值(denormal number),一些特殊数值(无穷(Inf)与非数值(NaN)),以及这些数值的「浮点数运算子」;它也指明了四种数值修约规则和五种例外状况(包括例外发生的时机与处理方式) 该标准的全称为IEEE二进位浮点数算术标准(ANSI/IEEE Std 754-1985),又称IEC 60559:1989,微处理器系统的二进位浮点数算术(本来的编号是IEC 559:1989)。

后来还有「与基数无关的浮点数」的「IEEE 854-1987标准」,有规定基数为2跟10的状况。现在最新标准是「IEEE 854-2008标准」。

IEEE 754 标准规定了计算机程序设计环境中的二进制和十进制的浮点数自述的交换、算术格式以及方法。


特殊的 Number 值


几个特殊值也被定义为 Number 类型。前两个是 Number.MAX_VALUENumber.MIN_VALUE,它们定义了 Number 值集合的外边界。所有 ECMAScript 数都必须在这两个值之间。不过计算生成的数值结果可以不落在这两个值之间。

当计算生成的数大于 Number.MAX_VALUE 时,它将被赋予值 Number.POSITIVE_INFINITY,意味着不再有数字值。同样,生成的数值小于 Number.MIN_VALUE 的计算也会被赋予值 Number.NEGATIVE_INFINITY,也意味着不再有数字值。如果计算返回的是无穷大值,那么生成的结果不能再用于其他计算。

事实上,有专门的值表示无穷大,(如你猜到的)即 InfinityNumber.POSITIVE_INFINITY 的值为 InfinityNumber.NEGATIVE_INFINITY 的值为 -Infinity

由于无穷大数可以是正数也可以是负数,所以可用一个方法判断一个数是否是有穷的(而不是单独测试每个无穷数)。可以对任何数调用isFinite()方法,以确保该数不是无穷大。对于数字可以调用Number.isInteger()验证数据是否是整型数据。

var temp = Number.POSITIVE_INFINITY;
console.log(isFinite(temp));//false
var temp = 5;
console.log(isFinite(temp));//true
console.log(Number.isInteger("0.55"))//false


最后一个特殊值是 NaN,表示非数(Not a Number)。NaN是个奇怪的特殊值。一般说来,这种情况发生在类型(StringBoolean 等)转换失败时。例如,要把单词 blue 转换成数值就会失败,因为没有与之等价的数值。与无穷大一样,NaN 也不能用于算术计算。NaN 的另一个奇特之处在于,它与自身不相等

    var temp =  NaN;
    console.log(NaN == temp);  //输出 "false"
    //出于这个原因,不推荐使用 NaN 值本身。函数 isNaN() 会做得相当好
    temp =  NaN;
    console.log(isNaN(temp));  //输出 "true"
    temp =  666;
    console.log(isNaN(temp));  //输出 "false"


Number 对象

new Number(value); 
var a = new Number('123'); // a === 123 is false
var b = Number('123'); // b === 123 is true
a instanceof Number; // is true
b instanceof Number; // is false

Number 对象是原始数值的包装对象。

  • 创建 Number 对象的语法:
var temp=new Number("a");
console.log(temp);
/*
Number {[[PrimitiveValue]]: NaN}
    __proto__:Number
    constructor:ƒ Number()
    toExponential:ƒ toExponential()
    toFixed:ƒ toFixed()
    toLocaleString:ƒ toLocaleString()
    toPrecision:ƒ toPrecision()
    toString:ƒ toString()
    valueOf:ƒ valueOf()
    __proto__:Object
    [[PrimitiveValue]]:0
[[PrimitiveValue]]:NaN
*/
var tmp=Number("b");
console.log(tmp);//NaN
tmp=Number("");
console.log(tmp);//0
  • 参数


参数 value 是要创建的 Number 对象的数值,或是要转换成数字的值。

  • 返回值


Number() 和运算符 new 一起作为构造函数使用时,它返回一个新创建的 Number 对象。如果不用 new 运算符,把 Number() 作为一个函数来调用,它将把自己的参数转换成一个原始的数值,并且返回这个值(如果转换失败,则返回 NaN)。

  • Number 对象属性
属性 描述
constructor 返回创建该实例对象的构造函数。默认为 Number 对象。
prototype Number 对象上允许的额外属性。
EPSILON 两个可表示(representable)数之间的最小间隔。
MAX_SAFE_INTEGER JavaScript 中最大的安全整数 (2 - 1)。
MAX_VALUE 能表示的最大正数。最小的负数是 -MAX_VALUE
MIN_SAFE_INTEGER JavaScript 中最小的安全整数 (-(2 - 1)).
MIN_VALUE 能表示的最小正数即最接近 0 的正数 (实际上不会变成 0)。最大的负数是 -MIN_VALUE
NaN 特殊的“非数字”值。
NEGATIVE_INFINITY 特殊的负无穷大值,在溢出时返回该值。
POSITIVE_INFINITY 特殊的正无穷大值,在溢出时返回该值。
  • Number 对象方法
方法 描述
isNaN() 确定传递的值是否是 NaN。
isFinite() 确定传递的值类型及本身是否是有限数。
isInteger() 确定传递的值类型是“number”,且是整数。
isSafeInteger() 确定传递的值是否为安全整数 ( -(2 - 1) 至 2 - 1之间)。
parseFloat() 和全局对象 parseFloat() 一样。
parseInt() 和全局对象 parseInt() 一样。
toString 把数字转换为字符串,使用指定的基数。
toLocaleString 把数字转换为字符串,使用本地数字格式顺序。
toFixed 把数字转换为字符串,结果的小数点后有指定位数的数字。
toExponential 把对象的值转换为指数计数法。
toPrecision 把数字格式化为指定的长度。
valueOf 返回一个 Number 对象的基本数字值。

example

使用 Number 对象给数字变量赋值

下例使用 Number 对象的属性给几个数字变量赋值:

var biggestNum = Number.MAX_VALUE;
var smallestNum = Number.MIN_VALUE;
var infiniteNum = Number.POSITIVE_INFINITY;
var negInfiniteNum = Number.NEGATIVE_INFINITY;
var notANum = Number.NaN;

整数类型的范围

JavaScript 能够准确表示的整数范围在-2^532^53之间(不含两个端点),超过这个范围,无法精确表示这个整数。 (详情请参阅 ECMAScript standard, chapter 6.1.6 The Number Type):

var biggestInt = Number.MAX_SAFE_INTEGER; 
//9007199254740991
var smallestInt = Number.MIN_SAFE_INTEGER; 
//-9007199254740991


在解析序列化的JSON时,如果JSON解析器将它们强制转换为Number类型,那么超出此范围的整数值可能会被破坏。在工作中使用String 类型代替,是一个可行的解决方案。


使用 Number 转换 Date 对象

下例使用 Number 作为函数来转换 Date 对象为数字值

var d = new Date("December 17, 1995 03:24:00");
console.log(Number(d));


这将输出 "819199440000"。


转换数字字符串为数字


Number('123')     // 123
Number('12.3')    // 12.3
Number('12.00')   // 12
Number('123e-1')  // 12.3
Number('')        // 0
Number(null)      // 0
Number('0x11')    // 17
Number('0b11')    // 3
Number('0o11')    // 9
Number('foo')     // NaN
Number('100a')    // NaN
Number('-Infinity') //-Infinity



本文使用 mdnice 排版