
第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