JavaScript 系列二:数据类型 (下)

goody
发布于 2021-7-21 15:30
浏览
0收藏

 

在下篇中,我们将继续讨论以下数据类型

String 类型
BigInt 类型
Symbol 类型
Object 类型
数值类型转换

 

String 类型


String (字符串)数据类型表示零或多个 16 位 Unicode 字符序列。字符串可以使用双引号( "" )、单引号('')或反引号( ` ` )标示。

let xhsFirstName = 'John'

let xhsLastName = 'Jacob'

let xhsLastName = `Jingleheimerschmidt`

let xhsError = 'Nicholas"; // 语法错误:开头和结尾的引号必须是同一种

 

字符字面量


语法


字面量是由语法表达式定义的常量,或通过由一定字词组成的语词表达式定义的常量。

字符串数据类型包含一些字符字面量,用于表示非打印字符或有其他用途的字符。

字 面 量 含 义
\n 换行
\t 制表
\b 退格
\r 回车
\f 换页
\ 反斜杠(\)
\ 单引号('),在字符串以单引号标示时使用,例如'He said, \'hey.\''
\" 双引号("),在字符串以双引号标示时使用,例如"He said, \"hey.\""
\` 反引号(\`),在字符串以反引号标示时使用,例如\` He said, \` hey.\``
\xnn 以十六进制编码 nn 表示的字符(其中 n 是十六进制数字 0~F),例如\x41 等于"A"
\unnnn 以十六进制编码 nnnn 表示的 Unicode 字符(其中 n 是十六进制数字 0~F),例如\u03a3 等于希腊字符"Σ"

 

这些字符字面量可以出现在字符串中的任意位置,且可以作为单个字符被解释:

let text = 'This is the letter sigma: \u03a3.'

 

在这个例子中,即使包含 6 个字符长的转义序列,变量 text 仍然是 28 个字符长。因为转义序列表示一个字符,所以只算一个字符。

console.log(text.length) // 28   字符串的长度获取

 

这个属性返回字符串中 16 位字符的个数。

 

注意: 如果字符串中包含双字节字符,那么 length 属性返回的值可能不是准确的字符数。


字符串的特点
字符串是不可变的,意思是一旦创建,它们的值就不能变了。要修改某个变量中的字符串值,必须先销毁原始的字符串,然后将包含新值的另一个字符串保存到该变量。

 

let lang = 'Java'

lang = lang + 'Script'

 

 

这里,变量 lang 一开始包含字符串"Java"。紧接着,lang 被重新定义为包含"Java""Script"的组合,也是"JavaScript"。整个过程首先会分配一个足够容纳 10 个字符的空间,然后填充上"Java""Script"。最后销毁原始的字符串"Java"和字符串"Script",因为这两个字符串都没有用了。

字符串插值

模板字面量最常用的一个特性是支持字符串插值,也就是可以在一个连续定义中插入一个或多个值。技术上讲,模板字面量不是字符串,而是一种特殊的 JavaScript 句法表达式,只不过求值后得到的是字符串。模板字面量在定义时立即求值并转换为字符串实例,任何插入的变量也会从它们最接近的作用域中取值。

字符串插值通过在 ${} 中使用一个 JavaScript 表达式实现:

let value = 5

let exponent = 'second'

// 以前,字符串插值是这样实现的:

let interpolatedString = value + ' to the ' + exponent + ' power is ' + value * value

// 现在,可以用模板字面量这样实现:

let interpolatedTemplateLiteral = `${value} to the ${exponent} power is ${value * value}`

console.log(interpolatedString) // 5 to the second power is 25

console.log(interpolatedTemplateLiteral) // 5 to the second power is 25

所有插入的值都会使用 toString() 强制转型为字符串,而且任何 JavaScript 表达式都可以用于插值。

  • 嵌套的模板字符串无须转义:
    console.log(`Hello, ${`World`}!`) // Hello, World!​
  • 将表达式转换为字符串时会调用 toString() :
    let foo = { toString: () => 'World' }
    
    console.log(`Hello, ${foo}!`) // Hello, World!​
  • 在插值表达式中可以调用函数和方法:
    function capitalize(word) {
      return `${word[0].toUpperCase()}${word.slice(1)}`
    }
    
    console.log(`${capitalize('hello')}, ${capitalize('world')}!`) // Hello, World!​

其他类型转换为字符串


有两种方式把一个值转换为字符串。首先是使用几乎所有值都有的 toString()方法。这个方法唯一的用途就是返回当前值的字符串等价物。

let xhsAge = 11
let xhsAgeAsString = xhsAge.toString() // 字符串"11"

let xhsFound = true
let xhsFoundAsString = xhsFound.toString() // 字符串"true"

toString()方法可见于数值、布尔值、对象和字符串值。(没错,字符串值也有 toString()方法,该方法只是简单地返回自身的一个副本。)null 和 undefined 值没有 toString() 方法。

多数情况下,toString() 不接收任何参数,默认情况下返回十进制,也可以通过参数来设置进制数。

let xhsNum = 10

console.log(xhsNum.toString()) // "10"

console.log(xhsNum.toString(2)) // "1010"

console.log(xhsNum.toString(8)) // "12"

console.log(xhsNum.toString(10)) // "10"

console.log(xhsNum.toString(16)) // "a"
注意,默认情况下(不传参数)的输出与传入参数 10 得到的结果相同。

如果你不确定一个值是不是 null 或 undefined ,可以使用 String() 转型函数,它始终会返回表示相应类型值的字符串。 String() 函数 遵循如下规则。

  • 如果值有 toString() 方法,则调用该方法(不传参数)并返回结果。
  • 如果值是 null ,返回 "null" 。
  • 如果值是 undefined,返回 "undefined" 。
    let xhsValue1 = 10
    let xhsValue2 = true
    let xhsValue3 = null
    let xhsValue4
    
    console.log(String(xhsValue1)) // "10"
    
    console.log(String(xhsValue2)) // "true"
    
    console.log(String(xhsValue3)) // "null"
    
    console.log(String(xhsValue4)) // "undefined"​

这里展示了将 4 个值转换为字符串的情况: 数值 、布尔值 、null 和 undefined 。

数值 和 布尔值 的转换结果与调用 toString() 相同。因为 null 和 undefined 没有 toString() 方法,所以 String() 方法就直接返回了这两个值的字面量文本。

注意: 用加号操作符给一个值加上一个空字符串""也可以将其转换为字符串

BigInt 类型

 

BigInt 是一种内置对象,它提供了一种方法来表示大于 2^53 - 1 的整数。这原本是 Javascript 中可以用 Number 表示的最大数字。 BigInt 可以表示任意大的整数。

描述 可以用在一个整数字面量后面加 n 的方式定义一个 BigInt ,如:10n,或者调用函数 BigInt() 。

const theBiggestInt = 9007199254740991n

const alsoHuge = BigInt(9007199254740991)
// ↪ 9007199254740991n

const hugeString = BigInt('9007199254740991')
// ↪ 9007199254740991n

const hugeHex = BigInt('0x1fffffffffffff')
// ↪ 9007199254740991n

const hugeBin = BigInt('0b11111111111111111111111111111111111111111111111111111')
// ↪ 9007199254740991n

 

它在某些方面类似于 Number ,但是也有几个关键的不同点:不能用于 Math 对象中的方法;不能和任何 Number 实例混合运算,两者必须转换成同一种类型。在两种类型来回转换时要小心,因为 BigInt 变量在转换成 Number 变量时可能会丢失精度。

Symbol 类型

 

symbol 是一种基本数据类型( primitive data type )。 Symbol() 函数会返回 symbol 类型的值,该类型具有静态属性和静态方法。它的静态属性会暴露几个内建的成员对象;它的静态方法会暴露全局的 symbol 注册,且类似于内建对象类,但作为构造函数来说它并不完整,因为它不支持语法:"new Symbol()"

每个从 Symbol() 返回的 symbol 值都是唯一的。一个 symbol 值能作为对象属性的标识符;这是该数据类型仅有的目的。

语法

参数 description 可选

Symbol([description])

 

可选的,字符串类型。对 symbol 的描述,可用于调试但不是访问 symbol 本身。

描述

直接使用 Symbol() 创建新的 symbol 类型,并用一个可选的字符串作为其描述。

var sym1 = Symbol()
var sym2 = Symbol('foo')
var sym3 = Symbol('foo')

 

上面的代码创建了三个新的 symbol 类型。 注意, Symbol("foo") 不会强制将字符串 “foo” 转换成 symbol 类型。它每次都会创建一个新的 symbol 类型:

Symbol('foo') === Symbol('foo') // false

下面带有 new 运算符的语法将抛出 TypeError 错误:

var sym = new Symbol() // TypeError

Object 类型

 

ECMAScript 中的对象其实就是一组数据和功能的集合。对象通过 new 操作符后跟对象类型的名称来创建。开发者可以通过创建 Object 类型的实例来创建自己的对象,然后再给对象添加属性和方法.

let xhsO = new Object()

ECMAScript 中的 Object 是派生其他对象的基类。 Object 类型的所有属性和方法在派生的对象上同样存在。每个 Object 实例都有如下属性和方法。

  • constructor :用于创建当前对象的函数。在前面的例子中,这个属性的值就是 Object() 函数。
  • hasOwnProperty(*propertyName*) :用于判断当前对象实例(不是原型)上是否存在给定的属性。要检查的属性名必须是字符串(如 o.hasOwnProperty("name") )或符号。
  • isPrototypeOf(*object*) :用于判断当前对象是否为另一个对象的原型。
  • propertyIsEnumerable(*propertyName*) :用于判断给定的属性是否可以使用 for-in 语句枚举。与 hasOwnProperty() 一样,属性名必须是字符串。
  • toLocaleString() :返回对象的字符串表示,该字符串反映对象所在的本地化执行环境。
  • toString() :返回对象的字符串表示。
  • valueOf() :返回对象对应的字符串、数值或布尔值表示。通常与 toString() 的返回值相同。

因为在 ECMAScript 中 Object 是所有对象的基类,所以任何对象都有这些属性和方法。

数值类型转换

 

有 3 个函数可以将非数值转换为数值: Number() 、 parseInt() 和 parseFloat() 。 Number() 是转型函数,可用于任何数据类型。后两个函数主要用于将字符串转换为数值。对于同样的参数,这 3 个函数执行的操作也不同。

Number() 函数

基于如下规则执行转换。

  • 布尔值, true 转换为 1 , false 转换为 0 。
  • 数值,直接返回。
  • null ,返回 0 。
  • undefined ,返回 NaN 。
  • 字符串,应用以下规则。

    • 如果字符串包含数值字符,包括数值字符前面带加、减号的情况,则转换为一个十进制数值。因此, Number("1") 返回 1 , Number("123") 返回 123 , Number("011") 返回 11 (忽略前面的零)。
    • 如果字符串包含有效的浮点值格式如 "1.1" ,则会转换为相应的浮点值(同样,忽略前面的零)。
    • 如果字符串包含有效的十六进制格式如 "0xf" ,则会转换为与该十六进制值对应的十进制整数值。
    • 如果是空字符串(不包含字符),则返回 0 。
    • 如果字符串包含除上述情况之外的其他字符,则返回 NaN 。
  • 对象,调用 valueOf() 方法,并按照上述规则转换返回的值。如果转换结果是 NaN ,则调用 toString() 方法,再按照转换字符串的规则转换。
    let xhsNum1 = Number('Hello world!') // NaN
    
    let xhsNum2 = Number('') // 0
    
    let xhsNum3 = Number('000011') // 11
    
    let xhsNum4 = Number(true) // 1​

parseInt() 函数

 

  • 字符串最前面的空格会被忽略,从第一个非空格字符开始转换
  • 如果第一个字符不是数值字符、加号或减号, parseInt() 立即返回 NaN
  • 如果第一个字符是数值字符、加号或减号,则继续依次检测每个字符,直到字符串末尾,或碰到非数值字符。比如, "1234blue" 会被转换为 1234 ,因为 "blue" 会被完全忽略。类似地, "22.5" 会被转换为 22 ,因为小数点不是有效的整数字符。

假设字符串中的第一个字符是数值字符, parseInt() 函数也能识别不同的整数格式(十进制、八进制、十六进制)。换句话说,如果字符串以 "0x" 开头,就会被解释为十六进制整数。如果字符串以 "0" 开头,且紧跟着数值字符,在非严格模式下会被某些实现解释为八进制整数。

let xhsNum1 = parseInt('1234blue') // 1234

let xhsNum2 = parseInt('') // NaN

let xhsNum3 = parseInt('0xA') // 10,解释为十六进制整数

let xhsNum4 = parseInt(22.5) // 22

let xhsNum5 = parseInt('70') // 70,解释为十进制值

let xhsNum6 = parseInt('0xf') // 15,解释为十六进制整数

parseInt() 也接收第二个参数,用于指定进制数。可以省略前面的 0x 或者 0

let xhsNum = parseInt('0xAF', 16) // 175

let xhsNum1 = parseInt('AF', 16) // 175

let xhsNum2 = parseInt('AF') // NaN

 

通过第二个参数,可以极大扩展转换后获得的结果类型。

let xhsNum1 = parseInt('10', 2) // 2,按二进制解析

let xhsNum2 = parseInt('10', 8) // 8,按八进制解析

let xhsNum3 = parseInt('10', 10) // 10,按十进制解析

let xhsNum4 = parseInt('10', 16) // 16,按十六进制解析

 

注意: 多数情况下解析的应该都是十进制数,此时第二个参数就要传入 10 。

parseFloat() 函数

 

该函数的工作方式跟 parseInt() 函数类似,都是从位置 0 开始检测每个字符。同样,它也是解析到字符串末尾或者解析到一个无效的浮点数值字符为止。这意味着第一次出现的小数点是有效的,但第二次出现的小数点就无效了,此时字符串的剩余字符都会被忽略。因此, "22.34.5" 将转换成 22.34 。

注意

  • 它始终忽略字符串开头的零
  • 十六进制数值始终会返回 0
  • 如果字符串表示整数(没有小数点或者小数点后面只有一个零),则 parseFloat() 返回整数
    let xhsNum1 = parseFloat('1234blue') // 1234,按整数解析
    
    let xhsNum2 = parseFloat('0xA') // 0
    
    let xhsNum3 = parseFloat('22.5') // 22.5
    
    let xhsNum4 = parseFloat('22.34.5') // 22.34
    
    let xhsNum5 = parseFloat('0908.5') // 908.5
    
    let xhsNum6 = parseFloat('3.125e7') // 31250000​

 

题目自测

一:null 和 undefined 的区别是什么?

二:以下代码,哪个结果返回的是 NaN()

A. let a = Number('')

B. let b = Number('xhs')

C. let c = Number(true)

D. let d = Number(120);

三: 以下代码输出什么?

let a = 12
let b = false
let c = null
let d = undefined
console.log(typeof a.toString())
console.log(typeof b.toString())
console.log(String(c))
console.log(String(d))

题目解析

 

一、
null 和 undefined 都是基本的数据类型,它们都本身都只有一个值,就是 null 和 undefined 。 undefined 表示未定义,null 表示为空对象。

null == undefined // true
null === undefined // false

Number(null) // 0
Number(undefined) // NaN

二、
Answr:B

此处用到了数值类型转换中的 Number() 函数

A 为空字串,转换之后返回的是 0 , B 字符串中的其他类型,转化为 NaN ,C true 会先转化为 1 ,然后转化为数值,D 普通数值,返回原来的值,所以是 120

三、
toString() 方法将值都转化为字符串的方式输出。然而 null 和 undefined 没有 toString() 方法,可以使用 String() 直接转化为字符串。

// 'string'
// 'string'
// 'null'
// 'undefined'

分类
已于2021-7-21 15:30:11修改
收藏
回复
举报
回复
    相关推荐