JavaScript编程思想:从ES5到ES9
上QQ阅读APP看书,第一时间看更新

第3章 数据类型

不同的编程语言存在不同的数据类型(data type),各种数据类型可用来描述容纳特不同数据的数据结构(data structure)。特定表达式被评估时,可返回特定类型的数据。

3.1 数值类型

JavaScript语言的数值,不仅包括整数(integer),也包含带有小数部分的浮点数(floating-point number)。

3.1.1 2n进制的字面量(ES6)

2n进制主要是指二进制、八进制与十六进制。在JavaScript语言中,可通过2n进制的字面量(literal),来表示2n进制的数字常量(number constant)/ 数值(number value)。

【3-1-1-nth-power-of-2-based-literals.js】

    var number01 = 111 ;
    var number02 = parseInt('111', 16) ;
    var number03 = 0x111 ;
    var number04 = 0111 ; // cannot use in strict mode.
    var number05 = parseInt('111', 8) ;
    var number06 = 0o111 ; // new literal in ES6
    var number07 = parseInt('111', 2) ;
    var number08 = 0b111 ; // new literal in ES6

    console.log(number01) ;
    console.log(number02) ;
    console.log(number03) ;
    console.log(number04) ;
    console.log(number05) ;
    console.log(number06) ;
    console.log(number07) ;
    console.log(number08) ;

【相关说明】

    var number01 = 111 ;

111代表十进制的数值111。

    var number02 = parseInt('111', 16) ;

parseInt('111', 16)返回十六进制数值111所对应的十进制数值273。

    var number03 = 0x111 ;

0x111代表十六进制的数值111。因此,变量number03的初始数值,会成为十六进制数值111所对应的十进制数值273。

    var number04 = 0111 ; // cannot use in strict mode.

0111代表八进制的数值111。因此,变量number04的初始数值,会成为八进制数值111所对应的十进制数值73。

    var number05 = parseInt('111', 8) ;

parseInt('111', 8)会返回八进制数值111所对应的十进制数值73。

    var number06 = 0o111 ; // new literal in ES6

0o111代表八进制的数值111。因此,变量number06的初始数值,会成为八进制数值111所对应的十进制数值73。

    var number07 = parseInt('111', 2) ;

parseInt('111', 2)会返回二进制数值111所对应的十进制数值7。

    var number08 = 0b111 ; // new literal in ES6

0b111代表二进制的数值111。因此,变量number08的初始数值,会成为二进制数值111所对应的十进制数值7。

3.1.2 数值的比较(ES6)

要比较两个数值类型的操作数(operand)的数值(number value)是相等、不相等、大于或小于的关系,必须通过带有特定比较运算符的表达式来实现。关于数值的比较,可参考如下示例。

【3-1-2-number-comparisons.js】

    console.log(3 + 0.1416 === 3.1416) ;
    console.log(0.5 + 0.25 === 0.75) ;
    console.log('') ;

    console.log(0.1 + 0.02 === 0.12) ;

    a = 0.1 ;
    b = 0.02 ;
    c = 0.12 ;
    console.log(a + b === c) ;
    console.log(Math.abs(a + b - c) < Number.EPSILON) ;

【相关说明】

    console.log(3 + 0.1416 === 3.1416) ;
    console.log(0.5 + 0.25 === 0.75) ;

在这两个语句中的比较表达式里,比较运算符【===】两侧操作数的数值,被判断为均相等,以及其数据类型均为浮点数(floating-point number)。

    console.log('') ;

    console.log(0.1 + 0.02 === 0.12) ;

在这个语句中,虽然比较运算符【===】两侧的数值,看起来是相等的,但是判断的结果却为假而返回布尔值false。

计算机的浮点数表示法,无法完整表示大部分的浮点数,所以计算机进行浮点数的运算时,常常会出现小数部分的截断误差(truncation error)。看似简单浮点数的比较运算,对计算机来说,反而是困难的任务。

    a = 0.1 ;
    b = 0.02 ;
    c = 0.12 ;

这3个语句声明了初始数值为不同浮点数的变量a、b与c。

    console.log(a + b === c) ;

虽然比较运算符【===】两侧的数值,看起来是相等的,但是判断的结果却为假而返回布尔值false。

    console.log(Math.abs(a + b - c) < Number.EPSILON) ;

【Number.EPSILON】是内置对象Number中的常量属性EPSILON,用来表示浮点数运算之后,可被容忍的截断误差值。因此,欲正确比较浮点数,表达式【a + b === c】应该被改写成为【Math.abs(a+ b - c) < Number.EPSILON】。

3.1.3 数值的正负符号(ES6)

在JavaScript语言中,数值可以是负数、正数或零值,而且零值还可以分为正零和负零。关于数值的正负符号的判断与诠释,可参考如下示例。

【3-1-3-number-sign-deteminations.js】

    console.log(Math.sign(0)) ;
    console.log(Math.sign(-0)) ;

    console.log(Math.sign(123)) ;
    console.log(Math.sign(-123)) ;

    console.log(Math.sign(null)) ;

    console.log(Math.sign(NaN)) ;
    console.log(Math.sign('Hello')) ;
    console.log(Math.sign(undefined)) ;

【相关说明】

函数Math.sign(特定变量名称)的返回值,可用来判断特定变量的如下特征:

• 其返回值为0,代表特定变量的数值亦为0。

• 其返回值为-0,代表特定变量的数值亦为-0。

• 其返回值为1,代表特定变量的数值为正数,例如123、23.8、1250.75。

• 其返回值为-1,代表特定变量的数值为负数,例如-123、-29.15、-2500.88。

• 其返回值为NaN(not a number),代表特定变量的数据,无法被转换成为数值,例如NaN、undefined、'Hello'、'125a'。

    console.log(Math.sign(0)) ;

Math.sign(0)的返回值为0。

    console.log(Math.sign(-0)) ;

Math.sign(-0)的返回值为-0。

    console.log(Math.sign(123)) ;

Math.sign(123)的返回值为1。

    console.log(Math.sign(-123)) ;

Math.sign(-123)的返回值为-1。

    console.log(Math.sign(null)) ;

Math.sign(null)的返回值为0。

    console.log(Math.sign(NaN)) ;

Math.sign(NaN)的返回值为NaN。其中,NaN的含义表示并非一个数值(not a number)。

    console.log(Math.sign('Hello')) ;

Math.sign('Hello')的返回值为NaN。

    console.log(Math.sign(undefined)) ;

Math.sign(undefined)的返回值为NaN。

3.1.4 数值的截断(ES6)

数值的截断(truncation),是指对于特定浮点数,先进行无条件四舍五入数值修约,再去除其小数,转换成为整数的过程。关于数值的截断的综合运用,可参考如下示例。

【3-1-4-number-truncations.js】

    v01 = 12.5 ;
    v02 = 12.3 ;
    v03 = 0.56 ;
    v04 = -0.83 ;

    console.log(parseInt(v01)) ;
    console.log(Math.trunc(v01)) ;
    console.log(Math.floor(v01)) ;
    console.log(Math.round(v01)) ;
    console.log(Math.ceil(v01)) ;
    console.log('') ;

    console.log(parseInt(v02)) ;
    console.log(Math.trunc(v02)) ;
    console.log(Math.floor(v02)) ;
    console.log(Math.round(v02)) ;
    console.log(Math.ceil(v02)) ;
    console.log('') ;

    console.log(parseInt(v03)) ;
    console.log(Math.trunc(v03)) ;
    console.log(Math.floor(v03)) ;
    console.log(Math.round(v03)) ;
    console.log(Math.ceil(v03)) ;
    console.log('') ;

    console.log(parseInt(v04)) ;
    console.log(Math.trunc(v04)) ;
    console.log(Math.floor(v04)) ;
    console.log(Math.round(v04)) ;
    console.log(Math.ceil(v04)) ;
    console.log('') ;

    console.log(0 === -0) ;
    console.log(+0 === -0) ;

【相关说明】

    v01 = 12.5 ;
    v02 = 12.3 ;
    v03 = 0.56 ;
    v04 = -0.83 ;

这4个语句声明了初始数据为不同浮点数的变量v01、v02、v03与v04。

    console.log(parseInt(v01)) ;

调用内置函数parseInt(v01),会返回变量v01的数值12.5的整数部分12。

    console.log(Math.trunc(v01)) ;

调用内置函数Math.trunc(v01),会返回变量v01的数值12.5的整数部分12。

    console.log(Math.floor(v01)) ;

调用内置函数Math.floor(v01),会返回小于接近变量v01的数值12.5的整数值12。

    console.log(Math.round(v01)) ;

调用内置函数Math.round(v01),会返回对变量v01的数值12.5进行四舍五入之后的整数值13。

    console.log(Math.ceil(v01)) ;

调用内置函数Math.ceil(v01),会返回大于接近变量v01数值12.5的整数值13。

    console.log(parseInt(v02)) ;

调用内置函数parseInt(v02),会返回变量v02的数值12.3的整数部分12。

    console.log(Math.trunc(v02)) ;

调用内置函数Math.trunc(v02),会返回变量v02的数值12.3的整数部分12。

    console.log(Math.floor(v02)) ;

调用内置函数Math.floor(v02),会返回小于接近变量v02的数值12.3的整数值12。

    console.log(Math.round(v02)) ;

调用内置函数Math.round(v02),会返回对变量v02的数值12.3进行四舍五入之后的整数值12。

    console.log(Math.ceil(v02)) ;

调用内置函数Math.ceil(v02),会返回大于接近变量v02的数值12.3的整数值13。

    console.log(parseInt(v03)) ;

调用内置函数parseInt(v03),会返回变量v03的数值0.56的整数部分0。

    console.log(Math.trunc(v03)) ;

调用内置函数Math.trunc(v03),会返回变量v03的数值0.56的整数部分0。

    console.log(Math.floor(v03)) ;

调用内置函数Math.floor(v03),会返回小于接近变量v03的数值0.56的整数值0。

    console.log(Math.round(v03)) ;

调用内置函数Math.round(v03),会返回对变量v03的数值0.56进行四舍五入之后的整数值1。

    console.log(Math.ceil(v03)) ;

调用内置函数Math.ceil(v03),会返回大于接近变量v03的数值0.56的整数值1。

    console.log(parseInt(v04)) ;

调用内置函数parseInt(v04),会返回变量v04的数值-0.83的整数部分0。

    console.log(Math.trunc(v04)) ;

调用内置函数Math.trunc(v04),会返回变量v04的数值-0.83的整数部分-0。

    console.log(Math.floor(v04)) ;

调用内置函数Math.floor(v04),会返回小于接近变量v04的数值-0.83的整数值-1。

    console.log(Math.round(v04)) ;

调用内置函数Math.round(v04),会返回对变量v04的数值-0.83进行四舍五入之后的整数值-1。

    console.log(Math.ceil(v04)) ;

调用内置函数Math.ceil(v04),会返回大于但接近变量v04的数值-0.83的负整数值-0。

    console.log(0 === -0) ;

【0 === -0】返回布尔值true,所以0与-0的数值相等、数据类型相同。

    console.log(+0 === -0) ;

【+0 === -0】返回布尔值true,所以+0与-0的数值相等、数据类型相同。

3.1.5 数值的特殊格式(ECMA-402)

在此,数值的特殊格式,是指千分位(thousands)或者货币(currency)形式的数值表示方式。关于数值的特殊格式的综合运用,可参考如下示例。

【3-1-5-number-formattings.js】

    var nf_en = Intl.NumberFormat("en") ;
    var nf_de = Intl.NumberFormat("de") ;

    var number01 = 2533591.8 ;

    console.log(nf_en.format(number01)) ;
    console.log(nf_de.format(number01)) ;
    console.log('') ;

    console.log(number01.toString()) ;
    console.log(number01.toLocaleString()) ;
    console.log('') ;

    console.log(number01.toLocaleString('en')) ;
    console.log(number01.toLocaleString('de')) ;
    console.log('') ;

    // currency number format
    var cnf_cn = Intl.NumberFormat('cn', {style: 'currency', currency: 'cny'}) ;
    var cnf_jp = Intl.NumberFormat('jp', {style: 'currency', currency: 'jpy'}) ;
    var cnf_en = Intl.NumberFormat('en', {style: 'currency', currency: 'usd'}) ;
    var cnf_uk = Intl.NumberFormat('gb', {style: 'currency', currency: 'gbp'}) ; // Great Britain
     Pound
    var cnf_de = Intl.NumberFormat('de', {style: 'currency', currency: 'eur'}) ;

    var price01 = 25324700.56 ;

    console.log(cnf_cn.format(price01)) ;
    console.log(cnf_jp.format(price01)) ;
    console.log(cnf_en.format(price01)) ;
    console.log(cnf_uk.format(price01)) ;
    console.log(cnf_de.format(price01)) ;

【相关说明】

    var nf_en = Intl.NumberFormat("en") ;

Intl.NumberFormat对象的构造函数Intl.NumberFormat("en"),会返回【以字符串形式,表示英文(en, English)数值格式(number format)】的Intl.NumberFormat对象实例。因此,后续源代码,可借助其数据为Intl.NumberFormat对象实例的变量nf_en,将特定数值,表示成为英文数值格式化之后的字符串。

    var nf_de = Intl.NumberFormat("de") ;

Intl.NumberFormat("de")会返回【以字符串形式,表示德文/德国(de, DENIC eG for Germany)数值格式】的Intl.NumberFormat对象实例。因此,后续源代码,可借助其数据为Intl.NumberFormat对象实例的变量nf_de,将特定数值,表示成为德文数值格式化之后的字符串。

    var number01 = 2533591.8 ;

此语句声明了初始数据为2533591.8的变量number01。

    console.log(nf_en.format(number01)) ;

因为变量nf_en的数据为Intl.NumberFormat对象实例,所以存在可调用的函数format()。nf_en.format(number01)会返回【将变量number01的数值2533591.8,表示成为英文数值格式化】之后的字符串"2,533,591.8"。

    console.log(nf_de.format(number01)) ;

nf_en.format(number01)会返回【将变量number01的数值2533591.8,表示成为德文数值格式化】之后的字符串"2.533.591,8"。

    console.log('') ;

    console.log(number01.toString()) ;

number01.toString()仅会返回【将变量number01的数值2533591.8,转换成为字符串】之后的"2533591.8"。

    console.log(number01.toLocaleString()) ;

number01.toString()仅会返回【将变量number01的数值2533591.8,表示成为本地语言的数值格式化】之后的"2,533,591.8"。在此,本地语言为中文(cn, China)。

    console.log('') ;

    console.log(number01.toLocaleString('en')) ;

console.log(number01.toLocaleString('en'))和如下源代码片段之一,存在着异曲同工之妙:

• var nf_en = Intl.NumberFormat("en") ;

console.log(nf_en.format(number01));

• console.log(Intl.NumberFormat("en").format(number01)) ;

    console.log(number01.toLocaleString('de')) ;

number01.toLocaleString('de')和如下源代码片段之一,存在着异曲同工之妙:

• var nf_de = Intl.NumberFormat("de") ;

console.log(nf_de.format(number01)) ;

• console.log(Intl.NumberFormat("de").format(number01)) ;

    console.log('') ;

    // currency number format
    var cnf_cn = Intl.NumberFormat('cn', {style: 'currency', currency: 'cny'}) ;

Intl.NumberFormat对象的构造函数Intl.NumberFormat('cn', {style: 'currency', currency: 'cny'}),会返回【以字符串形式,表示中文/中国(cn, China)与人民币(cny, China Yuan)的数值格式】的Intl.NumberForma对象实例。后续源代码,可借助其数据为Intl.NumberFormat对象实例的变量cnf_cn,将特定数值,表示成为中文与人民币的数值格式化之后的字符串。

    var cnf_jp = Intl.NumberFormat('jp', {style: 'currency', currency: 'jpy'}) ;

Intl.NumberFormat('jp', {style: 'currency', currency: 'jpy'}),会返回【以字符串形式,表示日文(jp,Japan)与日币(jpy, Japan Yuan)的数值格式】的Intl.NumberFormat对象实例。后续源代码,可借助其数据为Intl.NumberFormat对象实例的变量cnf_jp,将特定数值,表示成为日文与日币的数值格式化之后的字符串。

    var cnf_en = Intl.NumberFormat('en', {style: 'currency', currency: 'usd'}) ;

Intl.NumberFormat('en', {style: 'currency', currency: 'usd'}),会返回【以字符串形式,表示英文(en,English)与美元(usd, United States Dollar)的数值格式的Intl.NumberFormat对象实例。后续源代码可借助其数据为Intl.NumberFormat对象实例的变量cnf_en,将特定数值,表示成为英文与美元的数值格式化之后的字符串。

    var cnf_uk = Intl.NumberFormat('gb', {style: 'currency', currency: 'gbp'}) ; // Great Britain
    Pound

Intl.NumberFormat('gb', {style: 'currency', currency: 'gbp'}),会返回【以字符串形式,表示英式英文(gb, Great Britain)与英镑(gbp, Great Britain Pound)的数值格式】的Intl.NumberFormat对象实例。后续源代码可借助其数据为Intl.NumberFormat对象实例的变量cnf_uk,将特定数值,表示成为英式英文与英镑的数值格式化之后的字符串。

    var cnf_de = Intl.NumberFormat('de', {style: 'currency', currency: 'eur'}) ;

Intl.NumberFormat('de', {style: 'currency', currency: 'eur'})会返回【以字符串形式,表示德文/德国(de, DENIC eG for Germany)与欧元(eur, Euro)的数值格式】的对象实例。后续源代码可借助其数据为Intl.NumberFormat对象实例的变量cnf_de,将特定数值,表示成为德文与欧元的数值格式化之后的字符串。

    var price01 = 25324700.56 ;

此语句声明了初始数据为25324700.56的变量price01。

    console.log(cnf_cn.format(price01)) ;

因为变量cnf_cn是Intl.NumberFormat对象实例,所以存在可调用的函数format()。cnf_cn.format(price01)会返回【将变量price01的数值25324700.56,表示成为人民币数值格式化】之后的字符串"CN¥25,324,700.56"。

    console.log(cnf_jp.format(price01)) ;

cnf_jp.format(price01)会返回【将变量price01的数值25324700.56,表示成为日币数值格式化】之后的字符串"JP¥25,324,701"。

    console.log(cnf_en.format(price01)) ;

cnf_en.format(price01)会返回【将变量price01的数值25324700.56,表示成为美元数值格式化】之后的字符串"$25,324,700.56"。

    console.log(cnf_uk.format(price01)) ;

cnf_uk.format(price01)会返回【将变量price01的数值25324700.56,表示成为英镑数值格式化】之后的字符串"£25,324,700.56"。

    console.log(cnf_de.format(price01)) ;

cnf_de.format(price01)会返回【将变量price01的数值25324700.56,表示成为德文欧元的数值格式化】之后的字符串"£25,324,700.56"。

关于语言代码(language code),例如cn、en、gb等,以及货币代码(currency code),例如cny、usd、gbp等,可参考如下网址的内容:

• 语言代码: en.wikipedia.org/wiki/Language_code

• 货币代码: en.wikipedia.org/wiki/ISO_4217

3.1.6 整数值的安全范围(ES6)

简单来说,JavaScript语言的整数值的安全范围是-(253 - 1) ~ +(253 - 1)。关于整数值的安全范围的理解,可参考如下示例。

【3-1-6-number-safe-ranges.js】

    console.log(Number.isNaN(NaN)) ;
    console.log(Number.isNaN(123)) ;

    console.log(Number.isFinite(456)) ;
    console.log(Number.isFinite(NaN)) ;

    console.log(Number.isFinite(Infinity)) ;
    console.log(Number.isFinite(-Infinity)) ;

    console.log('') ;

    console.log(Number.isSafeInteger(Math.pow(2, 48) + 100)) ;
    console.log(Number.isSafeInteger(Math.pow(2, 53) - 1)) ;
    console.log(Number.isSafeInteger(Math.pow(2, 53))) ;

【相关说明】

函数Number.isNaN(特定变量名称)的返回值,可用来判断特定变量的数值,是否并非一个数值(not a number):

• 其返回值为true,代表特定变量的数值,并不是一个数值。

• 其返回值为false,代表特定变量的数值,是一个数值。

    console.log(Number.isNaN(NaN)) ;

Number.isNaN(NaN)的返回值为true。

    console.log(Number.isNaN(123)) ;

Number.isNaN(123)的返回值为false。函数Number.isFinite(特定变量名称)的返回值,可用来判断特定变量的数值,是否为有限(finite)的数值:

• 其返回值为true,代表特定变量的数值,是计算机可明确表示的数值。

• 其返回值为false,代表特定变量的数值,并不是计算机可明确表示的数值。

    console.log(Number.isFinite(456)) ;

Number.isFinite(456)的返回值为true。

    console.log(Number.isFinite(NaN)) ;

Number.isFinite(NaN)的返回值为false。

    console.log(Number.isFinite(Infinity)) ;

Number.isFinite(Infinity)的返回值为false。

    console.log(Number.isFinite(-Infinity)) ;

Number.isFinite(-Infinity)的返回值为false。

函数Number.isSafeInteger(特定变量名称)的返回值,可用来判断特定变量的数值,是否为IEEE-754所规范的安全范围-(253 - 1) ~ +(253 - 1)里的整数值:

• 返回值为true,代表特定变量的数值,是安全范围内的整数值。

• 返回值为false,代表特定变量的数值,并不是安全范围内的整数值。

    console.log(Number.isSafeInteger(Math.pow(2, 48) + 100)) ;

Math.pow(2, 48) + 100的结果值为248 + 100。

Number.isSafeInteger(Math.pow(2, 48) + 100)的返回值为true。

    console.log(Number.isSafeInteger(Math.pow(2, 53) - 1)) ;

Math.pow(2, 53) - 1的结果值为253 - 1。

Number.isSafeInteger(Math.pow(2, 53) - 1)的返回值为true。

    console.log(Number.isSafeInteger(Math.pow(2, 53))) ;

Math.pow(2, 53)的返回值为253

Number.isSafeInteger(Math.pow(2, 53))的返回值为false。

    console.log(Math.pow(2, 64)) ;

Math.pow(2, 64)的返回值,理应为264,也就是18446744073709551616;但是,其真实的返回值却为18446744073709552000。所以,其最右侧的4位数,明显存在误差。有误差的缘故,就是因为264已经是超越安全范围的整数值了。

3.2 布尔类型

JavaScript布尔(boolean)类型的数据,只存在布尔值false(假)和布尔值true(真)两个组合。其中,false代表假、否、非、不对、不是等不成立的含义;true则代表真、对、是等成立的含义。

【3-2---Boolean-data-type.js】

    let passed = false, score = 0 ;

    score = 80 ;

    passed = score > 60 ;

    console.log(passed) ;

    score = 55 ;

    passed = score > 60 ;

    console.log(passed) ;
    console.log('') ;

    ///
    let conversion ;

    conversion = Boolean(-10.8) ;

    console.log(conversion) ;

    conversion = Boolean(15.6) ;

    console.log(conversion) ;

    console.log('') ;

    ///
    conversion = Boolean(0) ;

    console.log(conversion) ;

    conversion = Boolean(null) ;

    console.log(conversion) ;

    conversion = Boolean(false) ;

    console.log(conversion) ;

    conversion = Boolean('') ;

    console.log(conversion) ;

    conversion = Boolean(undefined) ;

    console.log(conversion) ;
    console.log('') ;

    ///
    conversion = new Boolean(-10.8) ;

    console.log(conversion.valueOf()) ;

    conversion = new Boolean(15.6) ;

    console.log(conversion.valueOf()) ;

    conversion = new Boolean(0) ;

    console.log(conversion.valueOf()) ;

【相关说明】

    let passed = false, score = 0 ;

此语句声明了初始数据为false的变量passed,以及初始数据为0的变量score。

    score = 80 ;

此语句赋予整数值80给变量score。

    passed = score > 60 ;

在此,【score > 60】是比较运算式,得出来的结果值为布尔值true,并被赋给变量passed。

    console.log(passed) ;

    score = 55 ;

此语句赋予整数值55给变量score。

    passed = score > 60 ;

此语句将【score > 60】的结果值false,赋给变量passed。

    console.log(passed) ;
    console.log('') ;

    ///
    let conversion ;

此语句声明了变量conversion。

    conversion = Boolean(-10.8) ;

-10.8是一个非0的数值,因此,经过Boolean对象的构造函数Boolean()处理之后,会返回true。

    console.log(conversion) ;

    conversion = Boolean(15.6) ;

15.6是一个非0的数值,因此,经过Boolean对象的构造函数Boolean()处理之后,会返回true。

    console.log(conversion) ;
    console.log('') ;

    ///
    conversion = Boolean(0) ;

    conversion = Boolean(null) ;

    conversion = Boolean(false) ;

    conversion = Boolean('') ;

    conversion = Boolean(undefined) ;

在前段各语句中,无论是0、null、false、空字符串''或undefined,均是具有零值意义的常量,经过构造函数Boolean()的处理之后,均会返回false。

    console.log(conversion) ;
    console.log('') ;

    conversion = new Boolean(-10.8) ;

    conversion = new Boolean(15.6) ;

    conversion = new Boolean(0) ;

在前段各语句中,构造函数Boolean()左侧被衔接了关键字new,使得变量conversion的数据,成为内含布尔值true或false的Boolean对象实例。

    console.log(conversion.valueOf()) ;

调用conversion.valueOf()函数,可返回变量conversion内含的布尔值true或false。

3.3 数组类型

数组(array)是用来表示一组【具有各自数据】的元素。然而,就JavaScript语言来说,其数组实例的数据类型(data type)为对象类型。数组实例中各元素的数据,可以同时存在数值布尔值字符串对象,甚至是子数组!关于数组类型的综合运用,可参考如下示例。

【3-3---Array-data-type.js】

    let numbers = [520, 530, 1314, 2013, 2014] ;
    let profile = ['Tommy', 'male', 33, [180, 72]] ;
    let newone = new Array(6) ;

    console.log(numbers) ;
    console.log(numbers[2]) ;

    numbers[1] = 2591.8 ;

    console.log(numbers) ;
    console.log(numbers.length) ;
    console.log('') ;

    ///
    console.log(profile) ;
    console.log(profile[0]) ;
    console.log(profile[2]) ;
    console.log(profile[3][0]) ;
    console.log(profile[3][1]) ;

    profile[3][1] = 70 ;

    console.log(profile) ;
    console.log(profile.length) ;
    console.log(profile[3].length) ;

    ///
    console.log(numbers[numbers.length]) ;
    console.log(profile[profile.length]) ;
    console.log('') ;
    console.log(newone[0]) ;
    console.log(newone[newone.length]) ;

【相关说明】

    let numbers = [520, 530, 1314, 2013, 2014] ;

此语句声明了初始数据为内含多个整数元素的数组实例[520, 530, 1314, 2013, 2014]的变量numbers。

    let profile = ['Tommy', 'male', 33, [180, 72]] ;

此语句声明了初始数据为数组实例['Tommy', 'male', 33, [180, 72]]的变量profile。

    let newone = new Array(6) ;

new Array(6)会返回内含6个空元素的数组实例。此语句声明了初始数据为内含6个空元素的数组实例的变量newone。

    console.log(numbers) ;

在网页浏览器的调试工具【Console】面板中,显示出[520, 530, 1314, 2013, 2014]的信息。

    console.log(numbers[2]) ;

numbers[2]会返回在变量numbers的数组实例中,其索引值为2(第3个)的元素值1314。

    numbers[1] = 2591.8 ;

数值2591.8被存为在变量numbers数组实例中,其索引值为1(第2个)的元素值。

    console.log(numbers) ;

显示出[520, 2591.8, 1314, 2013, 2014]的信息。

    console.log(numbers.length) ;

numbers.length会返回变量numbers数组实例中的元素个数。

    console.log(profile) ;

在网页浏览器的调试工具【Console】面板中,显示出可展开的["Tommy", "male", 33, Array(2)]信息。

展开上述信息之后,可看见Array(2)代表子数组实例[180, 70]。在此,应该为整数值72的,却被显示为如下屏幕快照里的整数值70,是因为调试工具的运行机制,即时响应了随后源代码的执行结果。

    console.log(profile[0]) ;

profile[0]会返回在变量profile的数组实例中,其索引值为0(第1个)的元素的数据"Tommy"。

    console.log(profile[2]) ;

profile[2]会返回在变量profile的数组实例中,其索引值为2(第3个)的元素的数值33。

    console.log(profile[3][0]) ;
    console.log(profile[3][1]) ;

profile[3]会返回在变量profile的数组实例中,其索引值为3(第4个)的元素的数据,也就是子数组实例[180,72]。

所以,profile[3][0]会返回在子数组实例[180, 72]中,其索引值为0(第1个)的元素的数值180。

profile[3][1]则会返回在子数组实例[180, 72]中,其索引值为1(第2个)的元素的数值72。

    profile[3][1] = 70 ;

此语句使得在profile[3]所代表的子数组实例[180, 72]中,其索引值为1(第2个)的元素的数值,被修改成为70。因此,子数组实例变更为[180, 70]。

    console.log(profile.length) ;

profile.length会返回在变量profile的数组实例中,其1元素的个数4。

    console.log(profile[3].length) ;

profile[3]代表子数组实例[180, 72]。profile[3].length会返回子数组实例[180,72]的元素个数2。

    console.log(numbers[numbers.length]) ;

numbers.length会返回变量numbers的数组实例中的元素个数5。

在变量numbers的数组实例中,若其索引值为5,则代表第6个元素的索引值。

在变量numbers的数组实例中,一开始并无第6个元素,所以,numbers[numbers.length]如同numbers[5]的语法,会返回undefined。

    console.log(profile[profile.length]) ;

profile.length会返回变量profile的数组实例中的元素个数4。在变量profile的数组实例中,若其索引值为4,则代表第5个元素的索引值。在变量profile的数组实例中,一开始并无第5个元素,所以profile[profile.length]如同是profile[4]的语法,会返回undefined。

    console.log(newone[0]) ;
    console.log(newone[newone.length]) ;

因为变量newone一开始为内含6个空元素的数组实例,所以newone[0]会返回undefined,newone.length会返回变量newone的数组实例中的元素个数6。在变量newone的数组实例中,若其索引值为6,则代表第7个元素的索引值。然而,一开始并无第7个元素,所以newone[newone.length]如同是newone[7]的语法,会返回undefined。

3.4 对象类型

对象(object)通过属性(property)和方法(method)/函数(function),模拟在真实世界中,具有身份数据(identity data)和表现特征行为(characteristic behavior)的物体(object)。关于对象类型的理解,可参考如下示例。

【3-4---Object-data-type.js】

    // let item01 = {} ;
    let item01 = new Object() ;

    item01.name = 'Tablet PC' ;
    item01.price = 1000 ;
    item01.origin = 'China' ;
    item01['manufacture date'] = '2018/12/15' ;
    item01['color'] = 'RoyalBlue' ;
    item01[''] = 'secret data...' ; // empty property name

    console.log(item01) ;
    console.log(item01['']) ;
    console.log(item01.color) ;
    console.log(item01['manufacture date']) ;
    console.log(item01.price) ;

    item01.price = 900 ;
    item01['color'] = 'Gold' ;

    console.log(item01) ;

【相关说明】

    // let item01 = {} ;
    let item01 = new Object() ;

通过关键字new和Object对象的构造函数Object()的语法,可返回Object对象的空实例(empty instance),或称为空的Object对象实例。在此,【= new Object()】等同于【= {}】的语法;而且此语句声明了初始数据为空的Object对象实例的变量item01。

    item01.name = 'Tablet PC' ;
    item01.price = 1000 ;
    item01.origin = 'China' ;

通过变量item01衔接点运算符【.】,可动态创建变量item01的Object对象实例的3个新属性name、price、origin及其个别的数据'Table PC'、1000、'China'。

    item01['manufacture date'] = '2018/12/15' ;
    item01['color'] = 'RoyalBlue' ;
    item01[''] = 'secret data...' ;  // empty property name

通过变量item01衔接中括号运算符[],亦可动态创建变量item01的Object对象实例的3个新属性manufacture date、color、'',以及其个别的数据'2018/12/15'、'RoyalBlue'、'secret data...'。值得注意的是,和衔接点运算符【.】比起来,衔接中括号运算符[]的方式,可创建具有如下特殊名称的属性:

• 带有空格(space)字符的属性名称,例如【manufacture date】。

• 空(empty)的属性名称,例如【''】。

    console.log(item01) ;

此语句使得网页浏览器在调试工具【Console】面板中,显示出如下信息:

    console.log(item01['']) ;

item01['']返回属性对应的数据"secret data..."。

    console.log(item01.color) ;

item01.color返回属性color对应的数据"RoyalBlue"。

    console.log(item01['manufacture date']) ;

item01['manufacture date']返回属性manufacture date对应的数据"2018/12/15"。

    console.log(item01.price) ;

item01.price返回属性price对应的数值1000。

    item01.price = 900 ;

此语句使得变量item01的属性price,重新被赋予整数值900。

    item01['color'] = 'Gold' ;

此语句使得变量item01的属性color,重新被赋予字符串'Gold'。

    console.log(item01) ;

再次通过此语句,查看变量item01的数据是否被变更了。

3.5 字符串类型

字符串(string)是具有一串字符(character)的文本数据。在各种应用程序的画面当中,显示给用户观看的文本,即是持续由多个字符串,拼凑而成的产物。

3.5.1 一般字符串

在JavaScript语言中,字符串的字面量(literal)均以【内含一串字符】的一对单引号或双引号来表示。关于一般字符串的运用,请看下面的示例。

【3-5-1-common-strings.js】

    let sentence = 'Hi,\n\tlong time no see!\nhow are you today?\n\nBest Regards,\nAlex' ;

    console.log(sentence) ;

    sentence = "Limit '3' days and \"5\" persons." ;

    console.log(sentence) ;

    sentence = '\\It costs \'370\' dollars.\\' ;

    console.log(sentence) ;

    sentence = 'Alex lovingly loves ' +
    'lovely beloved of ' +
    'Daisy.' ;

    console.log(sentence) ;

    sentence = 'Alex lovingly loves \
    lovely beloved of \
    Daisy.' ;

    console.log(sentence) ;
    console.log(sentence[0]) ;
    console.log(sentence[1]) ;
    console.log(sentence[2]) ;
    console.log(sentence[3]) ;
    console.log('') ;

    console.log(sentence.charAt(0)) ;
    console.log(sentence.charAt(1)) ;
    console.log(sentence.charAt(2)) ;
    console.log(sentence.charAt(3)) ;

【相关说明】

    let sentence = 'Hi,\n\tlong time no see!\nhow are you today?\n\nBest Regards,\nAlex' ;

此语句声明了初始数据为字符串的变量sentence。在此字符串中,存在多个换行(new line)字符'\n',以及间隔至多如同8个空格的制表(tab)字符'\t'。

    console.log(sentence) ;

此语句显示出变量sentence的如下数据字符串:

Hi,

long time no see!

how are you today?

Best Regards,

Alex

    sentence = "Limit '3' days and \"5\" persons." ;

此语句赋予新的字符串字面量,给变量sentence。在此语句中,通过一对双引号【""】,容纳字符串。然而,在此双引号之内,还存在其他单引号与双引号。

容纳字符串的一对双引号【""】或单引号【''】,不可以冲突于其内部的双引号或单引号!其内部发生冲突的引号左侧,必须衔接反斜杠(back slash)字符才行,例如:

• "...\".....\"....'..'...."

• '..."....."....\'..\'....'

    console.log(sentence) ;

此语句显示出变量sentence的数据字符串【Limit '3' days and "5" persons.】。

    sentence = '\\It costs \'370\' dollars.\\' ;

此语句将新的字符串字面量,赋给变量sentence。在此语句中,通过一对单引号【''】容纳字符串。然而,在单引号之内,还存在反斜杠和其他单引号字符。

在字符串内,单引号、反斜杠均是特殊字符,所以必须在其左侧,衔接额外的反斜杠字符,成为【\\】或【\'】,才能正常呈现在信息里。

    console.log(sentence) ;

此语句显示出变量sentence的数据字符串【\It costs '370' dollars.\】。

    sentence = 'Alex lovingly loves ' +
    'lovely beloved of ' +
    'Daisy.' ;

此语句被分成3行,在等号右侧,借助加法运算符【+】,进行3个字符串的合并运算。

    console.log(sentence) ;

此语句显示出多个字符串被合并之后的新字符串'Alex lovingly loves lovely beloved of Daisy.'。

    sentence = 'Alex lovingly loves \
    lovely beloved of \
    Daisy.' ;

此语句亦被分成3行,在等号右侧,借助反斜杠字符,串接字符串的各个片段。

欲使用此法,在各个反斜杠字符的右侧,不可再加上包括空格(space)在内的任何字符。

    console.log(sentence) ;

此语句亦显示出多个字符串被合并之后的新字符串'Alex lovingly loves lovely beloved of Daisy.'。

    console.log(sentence[0]) ;
    console.log(sentence[1]) ;
    console.log(sentence[2]) ;
    console.log(sentence[3]) ;

变量sentence目前的数据为字符串'Alex lovingly loves lovely beloved of Daisy.'。所以,将变量sentence的数据字符串,视为内含多个字符的数组实例时,每个元素的数据,即为各个单一字符。这4个语句分别显示出在变量sentence的数据字符串里,其第1个至第4个元素的数据字符'A'、'l'、'e'与'x'。

    console.log(sentence.charAt(0)) ;
    console.log(sentence.charAt(1)) ;
    console.log(sentence.charAt(2)) ;
    console.log(sentence.charAt(3)) ;

这4个语句较为正统,和前面4个语句有异曲同工之妙,亦可显示出在变量sentence的数据字符串里,其第1个至第4个元素的数据字符'A'、'l'、'e'与'x'。

3.5.2 格式化字符串(ES6)

在JavaScript语言中,所谓的格式化字符串(formatting string)的正式名称为模板字面量(template literal),可用来嵌入待评估的表达式。当这些表达式被评估完成而返回特定数据时,格式化字符串才能被确认最终的模样。关于格式化字符串的运用,可参考如下示例。

【3-5-2-string-interpolations.js】

    var users =
    [
      {name: 'John', age: '33', gender: 'male'},
      {name: 'Jessica', age: '27', gender: 'female'},
      {name: 'Daisy', age: '33', gender: 'female'},
      {name: 'Sean', age: '24', gender: 'male'}
    ] ;

    var nations = [ 'China', 'Canada', 'America', 'New Zeland'] ;

    var days_amount = 5 ;

    var flight_message = `${users[1].name} decides to flight to ${nations[0]} after ${days_amount}
      days.` ;

    console.log(flight_message) ;

    flight_message = `${users[3].name} decides to flight to ${nations[2]} after ${days_amount}
      days.` ;

    console.log(flight_message) ;

    var items =
    [
      {product_id: 15023, price: 330},
      {product_id: 16002, price: 500}
    ]

    var checkout_message = `This product costs ${items[1].price * 0.8}.` ;

    console.log(checkout_message) ;

    var string01 = 'Hello\nEarth!' ;
    var string02 = `Hello\nEarth!` ;
    var string03 = String.raw `Hello\nEarth!` ;

    console.log(string01) ;
    console.log(string02) ;
    console.log(string03) ;

    number_digits = '1 2 3 4 5 6 7' ;

    // string04 = String.raw({raw: 'a b c d e f g '}, '1',' ','2',' ','3',' ','4',' ','5',' ','6','
      ','7') ;
    string04 = String.raw({raw: 'a b c d e f g '}, ... number_digits) ;

    console.log(string04) ;

【相关说明】

    var users =
    [
      {name: 'John', age: '33', gender: 'male'},
      {name: 'Jessica', age: '27', gender: 'female'},
      {name: 'Daisy', age: '33', gender: 'female'},
      {name: 'Sean', age: '24', gender: 'male'}
    ] ;

此语句声明了初始数据为【内含4个对象实例的数组实例】的变量users。

    var nations = ['China', 'Canada', 'America', 'New Zeland'] ;

此语句声明了初始数据为【内含多个字符串的数组实例】的变量nations。

    var days_amount = 5 ;

此语句声明了初始数值为整数5的变量days_amount。

    var flight_message = `${users[1].name} decides to flight to ${nations[0]} after ${days_amount}
      days.` ;

此语句声明了初始数据为格式化字符串的变量flight_message。格式化字符串必须放入一对反引号(back quote)【``】中。在格式化字符串里,可通过${变量名称}或${可评估的表达式}的语法,将特定变量的数据或者表达式被评估之后的数据,放置于格式化字符串里。

    console.log(flight_message) ;

此语句显示出变量flight_message的数据,也就是已经被转换完成的字符串'Jessica decides to flight to China after 5 days.'。

    flight_message = `${users[3].name} decides to flight to ${nations[2]} after ${days_amount}
      days.` ;

此语句使得变量flight_message,被赋予另一个格式化字符串。

    console.log(flight_message) ;

此语句显示出变量flight_message的数据,也就是已经被转换完成的字符串'Sean decides to flight to America after 5 days.'。

    var items =
    [
      {product_id: 15023, price: 330},
      {product_id: 16002, price: 500}
    ]

此语句声明了初始数据为【内含对象实例的数组实例】的变量items。

    var checkout_message = `This product costs ${items[1].price * 0.8}.` ;

此语句声明了初始数据为格式化字符串的变量checkout_message。

    console.log(checkout_message) ;

此语句显示出变量checkout_message的数据,也就是已经被转换完成的字符串'This product costs 400.'。

    var string01 = 'Hello\nEarth!' ;

此语句通过单引号【''】,声明了初始数据为一般字符串的变量string01。

    var string02 = `Hello\nEarth!` ;

此语句通过反引号【``】,声明了初始数据为格式化字符串的变量string02。

    var string03 = String.raw `Hello\nEarth!` ;

此语句通过内置的String对象的函数raw(),保留其中各字符的原始编码,并声明了初始数据为原始(raw)字符串的变量string03。也就是说,在字符串里的【\n】,已经被视为一般的字符【\】与【n】,而不再具有换行(new line)的特征。

值得注意的是,raw()明明是一个函数,在此却不能衔接一对小括号,而是衔接一对反引号,以实现出一个原始字符串。

    console.log(string01) ;
    console.log(string02) ;

这两个语句显示的信息相同,具体如下:

Hello

Earth!

    console.log(string03) ;

此语句显示的信息是【Hello\nEarth!】,【\n】的两个字符【\】与【n】均被保留了下来。

    number_digits = '1 2 3 4 5 6 7' ;

此语句声明了初始数据为字符串的变量number_digits。

    // string04 = String.raw({raw: 'a b c d e f g '}, '1',' ','2',' ','3',' ','4',' ','5',' ','6','
      ','7') ;
    string04 = String.raw({raw: 'a b c d e f g '}, ... number_digits) ;

等号右侧的String.raw(),会返回交叉分组之后的字符串"a1 b2 c3 d4 e5 f6 g7 "。在此,如下语法是等价的:

• String.raw({raw: 'a b c d e f g '}, ... number_digits)

• String.raw({raw: 'a b c d e f g '}, '1',' ','2',' ','3',' ','4',' ','5',' ','6',' ','7')

    console.log(string04) ;

此语句显示出变量string04的数据,也就是被交叉分组之后的字符串"a1 b2 c3 d4 e5 f6 g7 "。

3.5.3 日期与时间格式的字符串(ES6)

内含日期(date)与时间(time)相关数据的字符串,可被称为日期与时间格式的字符串。关于日期与时间格式的字符串的运用,可参考如下示例。

【3-5-3-date-and-time-strings.js】

    var dt_cn = new Intl.DateTimeFormat('cn') ;
    var dt_en = new Intl.DateTimeFormat('en') ;
    var dt_de = new Intl.DateTimeFormat('de') ;

    origin_datetime = new Date('2018-01-23') ;

    console.log(origin_datetime.toDateString()) ;
    console.log(origin_datetime.toLocaleDateString()) ;

    console.log('') ;

    dt01 = dt_cn.format(origin_datetime) ;
    dt02 = dt_en.format(origin_datetime) ;
    dt03 = dt_de.format(origin_datetime) ;

    console.log(dt01) ;
    console.log(dt02) ;
    console.log(dt03) ;

【相关说明】

    var dt_cn = new Intl.DateTimeFormat('cn') ;

Intl.DateTimeFormat对象的构造函数Intl.DateTimeFormat("cn"),会返回中文/中国(cn, China)格式的Intl.DateTimeFormat对象实例。后续源代码可借助变量dt_cn中的Intl.DateTimeFormat对象实例,将其他格式的日期与时间,表示成为中文格式的日期与时间。

    var dt_en = new Intl.DateTimeFormat('en') ;

Intl.DateTimeFormat对象的构造函数Intl.DateTimeFormat("en")会返回英文(en, English)格式的Intl.DateTimeFormat对象实例。后续源代码可借助变量dt_en中的Intl.DateTimeFormat对象实例,将其他格式的日期与时间,表示成为英文格式的日期与时间。

    var dt_de = new Intl.DateTimeFormat('de') ;

Intl.DateTimeFormat对象的构造函数Intl.DateTimeFormat("de")会返回德文/德国(de, DENIC eG for Germany)格式的Intl.DateTimeFormat对象实例。后续源代码可借助变量dt_de中的Intl.DateTimeFormat对象实例,将其他格式的日期与时间,表示成为德文格式的日期与时间。

    origin_datetime = new Date('2018-01-23') ;

此语句声明了变量origin_datetime,并被初始化为【日期是2018/01/23】的Date对象实例。在此,Date('2018-01-23')或Date('2018/01/23')均可被解读成功。

    console.log(origin_datetime.toDateString()) ;

origin_datetime.toDateString()会返回字符串'Tue Jan 23 2018'。

    console.log(origin_datetime.toLocaleDateString()) ;

origin_datetime.toLocaleDateString()会返回字符串'2018/1/23'。

    dt01 = dt_cn.format(origin_datetime) ;

因为变量dt_cn的数据是Intl.DateTimeFormat对象实例,所以存在可调用的函数format()。dt_cn.format(origin_datetime)会返回【在变量origin_datetime的Date对象实例中,其内含的日期与时间,被表示成为中文格式】之后的字符串'2018/1/23'。

    dt02 = dt_en.format(origin_datetime) ;

因为变量dt_en的数据是Intl.DateTimeFormat对象实例,所以存在可调用的函数format()。dt_en.format(origin_datetime)会返回【在变量origin_datetime的Date对象实例中,其内含的日期与时间,被表示成为英文格式】之后的字符串'1/23/2018'。

    dt03 = dt_de.format(origin_datetime) ;

因为变量dt_de的数据是Intl.DateTimeFormat对象的实例,所以存在可调用的函数format()。dt_de.format(origin_datetime)会返回【在变量origin_datetime的Date对象实例中,其内含的日期与时间,被表示成为德文格式】之后的字符串'23.1.2018'。

3.6 集合与地图类型

对JavaScript语言来说,集合(set)与地图(map)主要可用来简化编程的负担,是从ECMAScript 2015(ES6)版本开始,才具有的数据类型。

3.6.1 集合类型(ES6)

集合(set)内含其数据均不重复的元素,和数学理论中的集合,有着非常相似的含义与原理。换句话说,在特定集合内,只存在其数据不相同的元素。关于集合的运用,可参考如下示例。

【3-6-1-Set-data-type.js】

    let actions = new Set() ;

    actions.add('read') ;
    actions.add('write').add('update') ;
    actions.add('delete') ;

    actions.add('read').add('read').add('delete').add('write').add('update') ;

    console.log(actions) ;

    console.log(actions.entries()) ;
    console.log(actions.keys()) ;
    console.log(actions.values()) ;
    console.log('') ;

    for (let element of actions)
    {
      console.log(element) ;
    }

    console.log('') ;
    console.log(actions.size) ;

    console.log(actions.has('hide')) ;
    console.log(actions.has('write')) ;

【相关说明】

    let actions = new Set() ;

此语句声明了初始数据为【空的Set对象实例】的变量actions。

    actions.add('read') ;

当前变量actions的数据为一个Set对象实例,因此存在可调用的函数add()。在变量actions的Set对象实例中,添加数据为字符串'read'的新元素。

    actions.add('write').add('update') ;

此语句使得在变量actions的Set对象实例中,连续添加数据为字符串'write'与'update'的两个新元素。

    actions.add('delete') ;

此语句使得在变量actions的Set对象实例中,添加数据为字符串'delete'的新元素。

    actions.add('read').add('read').add('delete').add('write').add('update') ;

在变量actions的Set对象实例中,连续添加数据为字符串'read'、'read'、'delete'、'write'与'update'的5个新元素。在这5个新元素里,存在重复的数据字符串;所以,被添加至变量actions的Set对象实例中的时候,重复的元素会自动被排除在外。

    console.log(actions) ;

此语句显示出变量actions的Set对象实例【Set(4) {"read", "write", "update", "delete"}】的信息。在此,亦可看出在这个Set对象实例中,的确没有数据相同的元素。

    console.log(actions.entries()) ;
    console.log(actions.keys()) ;
    console.log(actions.values()) ;

这3个语句皆显示出相同的信息【SetIterator {"read", "write", "update", "delete"}】。其中,Set Iterator具有集合迭代器的含义。

    for (let element of actions)
    {
     console.log(element) ;
    }

通过循环语句for ... of的迭代处理,可在每次循环中,显示出在变量actions的Set对象实例中,其特定元素的如下数据字符串:

• read

• write

• update

• delete

    console.log(actions.size) ;

actions.size会返回Set对象实例中的元素个数4。

    console.log(actions.has('hide')) ;

actions.has('hide')会返回false,意味着在Set对象实例中,并无数据字符串为'hide'的元素。

    console.log(actions.has('write')) ;

actions.has('write')会返回true,代表着在Set对象实例中,存在数据字符串为'write'的元素。

3.6.2 地图类型(ES6)

地图(map)内含【键名(key name对应到值(value/ 数据(data】的组合。地图与对象(object)极为相似,只是节省了对象的累赘和限制。关于地图的运用,可参考如下示例。

【3-6-2-Map-data-type.js】

    let items = new Map() ;

    items.set('slipper', 50) ;
    items.set('shoes', 200) ;
    items.set('pants', 100).set('shirt', 150) ;

    console.log(items) ;

    console.log(items.size) ;

    console.log(items.entries()) ;
    console.log(items.keys()) ;
    console.log(items.values()) ;

    for (let [product, price] of items)
    {
      console.log(`One ${product} costs ${price}.`) ;
    }

【相关说明】

    let items = new Map() ;

此语句声明了初始数据为【空的Map对象实例】的变量items。

    items.set('slipper', 50) ;

变量items的数据,当前为一个Map对象实例,因此存在可调用的函数set()。此语句使得在变量items的Map对象实例中,被添加键名为slipper、值为50的新元素。

    items.set('shoes', 200) ;

此语句使得在变量items的Map对象实例中,被添加键名为shoes、值为200的新元素。

    items.set('pants', 100).set('shirt', 150) ;

此语句使得在变量items的Map对象实例中,连续添加键名分别为pants与shirt、值分别为100与150的两个新元素。

    console.log(items) ;

此语句显示出在变量items的Map对象实例【Map(4) {"slipper" => 50, "shoes" => 200, "pants" =>100, "shirt" => 150}】的信息。

    console.log(items.size) ;

items.size会返回Map对象实例中的元素个数4。

    console.log(items.entries()) ;

此语句显示出MapIterator {"slipper" => 50, "shoes" => 200, "pants" => 100, "shirt" => 150}的信息。其中,Map Iterator具有地图迭代器的含义。

    console.log(items.keys()) ;

此语句显示出MapIterator {"slipper", "shoes", "pants", "shirt"}的信息。

    console.log(items.values()) ;

显示出MapIterator {50, 200, 100, 150}的信息。

    for (let [product, price] of items)
    {
      console.log(`One ${product} costs ${price}.`) ;
    }

通过此循环语句for ... of的迭代处理,可在每次循环中,显示出在变量items的Set对象实例中,特定元素的如下数据字符串:

• One slipper costs 50.

• One shoes costs 200.

• One pants costs 100.

• One shirt costs 150.

值得注意的是,在上述循环语句的小括号里,【let [product, price] of items】的语句,使得在每次循环中:

• 变量product的数据,成为在变量items的Map对象实例中,特定元素的键名,例如slipper。

• 变量price的数据,成为在变量items的Map对象实例中,特定元素的值,例如50。

3.7 数据类型的转换(ES6)

对于各编程语言来说,特定变量在不同的时间点上,可被赋予不同类型的数据!在JavaScript引擎中,通过自动转换机制或者一些内置函数,可使得特定变量的数据,从原来的数据类型,转换成为新的数据类型。

最常见的数据类型的转换,莫过于【其他数据→字符串】和【字符串→数值】。关于数据类型的转换的综合运用,可参考如下示例。

【3-7---data-type-conversions.js】

    let digital_string = '  123  ' ;
    result = Number(digital_string) ;

    console.log(result) ;

    digital_string = '  0o123' ;
    result = Number(digital_string) ;

    console.log(result) ;

    digital_string = '0x123  ' ;
    result = Number(digital_string) ;

    console.log(result) ;

    result = parseInt(digital_string) ;

    console.log(result) ;

    result = Math.round(digital_string) ;

    console.log(result) ;
    console.log('') ;

    ///
    digital_string = '35.62' ;
    result = Math.floor(digital_string) ;

    console.log(result) ;

    digital_string = '28.2' ;
    result = Math.ceil(digital_string) ;

    console.log(result) ;

    digital_string = '12.5' ;
    result = Math.round(digital_string) ;

    console.log(result) ;

    ///
    let value = 53.8125 ;
    result = value.toString(2) ;

    console.log(result) ;

    result = value.toString(8) ;

    console.log(result) ;

    result = value.toString(16) ;

    console.log(result) ;

【相关说明】

    let digital_string = '  123  ' ;

此语句声明了初始数据为字符串' 123 '的变量digital_string。

    result = Number(digital_string) ;

通过内置的Number对象的构造函数Number(),将变量digital_string的数据字符串' 123 ' ,转换成十进制整数值123。在转换过程中,所有空格(space)字符皆会被过滤掉。

    digital_string = '  0o123' ;

将字符串' 0o123',赋给变量digital_string。

    result = Number(digital_string) ;

通过内置的Number对象的构造函数Number(),将变量digital_string的数据字符串' 0o123',先视为成八进制整数码123,再转换成为等价的十进制整数值83。

    digital_string = '0x123  ' ;

将字符串'0x123 '赋给变量digital_string。

    result = Number(digital_string) ;

通过内置的Number对象的构造函数Number(),将变量digital_string的数据字符串'0x123 ',先视为十六进制整数码123,再转换成为等价的十进制整数值291。

    result = parseInt(digital_string) ;
    result = Math.round(digital_string) ;

这两个语句皆可达成【将字符串'0x123 ',转换成为等价的十进制整数值291】的任务。

    digital_string = '35.62' ;
    result = Math.floor(digital_string) ;

这两个语句将字符串'35.62',转换成为十进制整数值35。

    digital_string = '28.2' ;
    result = Math.ceil(digital_string) ;

这两个语句将字符串'28.2',转换成为十进制整数值29。

    digital_string = '12.5' ;
    result = Math.round(digital_string) ;

这两个语句将字符串'12.5',转换成为十进制整数值13。

    let value = 53.8125 ;

此语句声明了初始数值为53.8125的变量value。

    result = value.toString(2) ;

value.toString(2)会返回转换之后的二进制数码110101.1101。

    result = value.toString(8) ;

value.toString(8)会返回转换后的八进制数码65.64。

    result = value.toString(16) ;

value.toString(16)会返回转换后的十六进制数码35.d。

3.8 练习题

1.在JavaScript语言里,应该使用什么语句,才能将浮点数25.75,分别表示成为二进制、八进制和十六进制数码的字符串?

2.在JavaScript语言里,应该使用什么语句,才能将二进制数码110111011,直接转换成为十六进制数码?

3.在JavaScript语言里,应该使用什么语句,才能直接将二进制数码101100011100、八进制数码1275、十六进制数码51cf的总和,转换成二进制数码?

4.已知变量x与y,请将3x2 + 2(x− 1)2y + 2xy2 + 5y3,编写成为JavaScript语言中的算术表达式

5.已知有如下主要表达式:

    let product = {item01: ['fruit_set', 100], item02: ['sticker_set', 250], item03: ['magnet_set',
      350], item04: ['drink_set', 150], item05: ['pizza_set', 300]} ;

请编写【将上述各个整数值总和,赋给变量result】的语句。

6.说明原始常量NaN、Infinity和undefined的含义。

7.执行如下JavaScript源代码片段之后,变量result的结果值是什么?

    let num01 = 28.56, num02 = 32.47 ;
    let result ;

    result = parseInt(num01) + Math.trunc(num01) + Math.floor(num01) + Math.round(num01) +
      Math.ceil(num01) ;

    result += parseInt(num02) + Math.trunc(num02) + Math.floor(num02) + Math.round(num02) +
      Math.ceil(num02) ;

8.请编写JavaScript源代码,使得变量price的数值72583000,显示成为货币数值格式字符串' CN¥72,583,000.00'。

9.列举两种JavaScript语法,来计算并显示【, where x=768】的数值。

10.列举两个等价于【price >= 300 && amount < 10】的比较与逻辑表达式。

11.已知如下数组实例:

    let arr = [[[5, 10], [15, 20]], [[25, 30], [35, 40]], [[45, 50], [55, 60]]] ;

访问上述整数值25、40和60的语法是什么?

12.已知如下对象实例:

    let obj = {product: {en: 'browser', cn: '浏览器' }, developer: {en: 'Google', cn: '谷歌'}, price:
      {en: 'free', cn: '免费'}} ;

访问字符串'browser'、'谷歌'与'free'的语法是什么?

13.已知数据为对象实例的变量profile和如下主要表达式:

    let message = profile.name + ' now lives on ' + profile.planet + '.' ;

让变量message被设置为相同数据字符串的等价语法是什么?

14.欲显示如下分行的信息:

    Apple: 11
    Banana: 15
    Guava: 23

其较为简短的JavaScript语法应该是什么?

15.欲显示当前的日期与时间,其较为简短的JavaScript语法应该是什么?

16.欲声明其数据为如下集合实例的变量components:

    Set(5) {"window", "pane", "dialogue", "button", "scrollbar"}

其较为简短的JavaScript语法应该是什么?

17.欲声明其数据为如下地图实例的变量devices:

    Map(4) {"mobile phone" => 10, "tablet PC" => 7, "notebook PC" => 3, "desktop PC" => 20}

其较为简短的JavaScript源代码应该是什么?

18.已知变量num的数值为十进制整数值201314,请编写【带有置入变量名称的模板字面量,并且显示如下信息】的JavaScript源代码:

    变量num的:
      十进制数值 = 201314
      二进制数码 = 110001001001100010
      八进制数码 = 611142
      十六进制数码 = 31262