JavaScript之数据类型(javascript常用的数据类型)
数据类型
简单数据类型(原始类型) Undefined、Null、Boolean、Number、String、Symbol(符号)
复杂数据类型(对象) Object(无序名值对的集合)
Undefined
使用 var let const 声明了变量但是没有初始化赋值时,就相当于给变量赋值了undefined
let message; console.log(message == undefined) // true复制代码
正常情况下不用显著的给变量设置undefined,undefined只是用来初始化变量,在ECMA-262第三版之前是不存在的,增加undefined与null本质的区别,null是明确确定空对象指针
undefined == null // true 会转换操作数复制代码
undefined是假值
Null
定义变量是对象,但是当时又没有哪个对象可保存,可以用null来填充,既能保持null是空对象指针的语义,又能与undefined区分开,又能检查变量是否被重新赋予了对象的引用
null 是假值
Boolean
字面量:true、false
区分大小写
转型函数 Boolean()
转换为true 没有
转换为false Boolean(undefined)
转换为true Boolean({}) 任意对象 Boolean(function() {})
转换为false Boolean(null) 空指针
转换为true Boolean(1) // 非0数值 无穷大也是 true Infinity Boolean(Infinity) // true Boolean(-Infinity) // true
转换为false Boolean(0) 0 和NaN
转换为true Boolean('dd') // 非空字符串
转换为false Boolean('') // 空字符串
转换为true Boolean(true)
转换为false Boolean(false)
Boolean 类型
String
Number
Object
Undefined
流程控制语句会自动执行其他类型值转换Boolean值的转换
Number
0 === -0 ﹢0永远 === -0
整数和浮点数
let floatNum = 3.125e7; // 等于31250000
规则:数值后面跟一个小写的e字母,加上乘以10的多少次幂
浮点数 科学计数法
值的范围
infinity 无穷大, -infinity负无穷大,不能在进行任何计算
isFinite() 判断是不是最大值函数
Number.MAX_VALUE 保存最大的值 1.797 693 134 862 315 7e+308
Number.MIN_VALUE 保存最小的值 5e-324
Number.NEGATIVE_INFINITY 捕获 -Infinity
Number.POSITIVE_INFINITY 获取 Infinity
NaN
能直接转数值的 返回 false
不能直接转数值的 返回 true
转换过程 先调用对象的valueOf(),能转换,直接返回,不能,在调用toString(),并测试转换值
表示不是数值,返回数值操作失败,不会抛出错误
不合法的转换数值操作都会返回NaN, 0/0
分母是0时,返回 Infinity 分母是-0,返回-Infinity
任何涉及与NaN操作都会返回NaN
NaN 不等于 包含NaN在内的任何值 NaN == NaN // false
isNaN() 参数是任何数据类型,判断参数是否不是数值
数值转换
与parseInt() 转换基础相同同,主要有几点不同
只能转换10进制
第一次出现的小数点是有效的,后面无效
let num1 = parseFloat("1234blue") // 1234 按整数解析 let num2 = parseFloat("0xA") // 0 let num3 = parseFloat("22.5") // 22.5 let num4 = parseFloat("22.34.5") // 22.34 let num5 = parseFloat("0908.5") // 908.5 let num6 = parseFloat("3.125e7") // 31250000复制代码
parseInt(value, 转换进制) // 2、8、10、16 避免系统出错,应该传第二个参数
专注字符串转数值
最前面的空格会被忽略,从第一个非空字符串开始转换
第一个字符不是数值字符,加号+,减号-,返回NaN // parseInt(' i1ddd1') // Nan
第一个字符是数值字符串,或者以加号+或者减号-,则会继续检测每个字段,直到结束,如果遇到非数值字符换转是数值的那些值 // parseInt(' 1dfdfd+0ddd1') // 1
遇到小数点也会忽略 parseInt(' 1.34') // 1
例子
转型函数,参数是任意类型
Boolean 类型,true为1 false为0
数值,直接返回
Null 转为0
Undefined 转为 NaN
String
let num1 = Number("Hello world!"); // NaN let num2 = Number(""); // 0 let num3 = Number("000011"); // 11 let num4 = Number(true);// 1复制代码
对象类型 转为NaN 规则 调用valueOf(),按string类型转换返回值,若是NaN,在调用toString(),按照转换字符串的规则进行转换
转换函数 Number()
parseInt()
parseFloat()
let num1 = parseInt("1234blue") // 1234
let num2 = parseInt("") // NaN
let num3 = parseInt("0xA") // 10,解释为十六进制整数
let num4 = parseInt(22.5) // 22
let num5 = parseInt("70") // 70,解释为十进制值
let num6 = parseInt("0xf")// 15,解释为十六进制整数
let num1 = parseInt("10", 2) // 2,按二进制解析
let num2 = parseInt("10", 8) // 8,按八进制解析
let num3 = parseInt("10", 10) // 10,按十进制解析
let num4 = parseInt("10", 16) // 16,按十六进制解析
字符串类型数值,包含'-','+',直接转为10进制,会自动忽略0,Number('01) // 1, Number('-00001') // -1
有效的字符串浮点类型数值,会直接转换相应的浮点数,会忽略0
包含有效的十六进制格式。'0xf',转换该十六进制对应的十进制的整数值
空字符串,转0
其余字符串会转为 NaN
String
声明 单引号'', 双引号"", 反引号``, 以什么引号开头就要以什么引号结束
let firstName = "John"
let firstName = 'John'
let firstName =
John
字符字面量
含有双字节字符,length不准确
用来表示非打印字符或其他用途字符,可以在字符串的任意位置
常见字面量
length 属性
\n 换行
\t 制表
\b 退格
\r 回车
\f 换页
\ 反斜杠(\)
' 单引号(')
" 双引号(")
` 反引号(`)
\xnn 以十六进制编码nn表示的字符(n表示十六进制数字0~F),'\x42' 表示 'A'
\unnnn 以十六进制编码nnnn表示Unicode字符(n表示十六进制数字0~F)'\u03a3' 表示希腊字符 'Σ'
字符串特点
声明的字符串是不可变的,修改变量值过程是先销毁原始字符串,在将新的字符串赋值该变量
早期浏览器拼接字符串非常慢,现已针对性优化
转为字符串
'' + 1 // '1'
返回当前值的字符串等价物
支持数值、布尔值、对象、字符值
null、undefined没有toString()
接受底数参数 默认是返回十进制的字符串
let value1 = 10; let value2 = true; let value3 = null; let value4; console.log(String(value1)); // "10" console.log(String(value2)); // "true" console.log(String(value3)); // "null" console.log(String(value4)); // "undefined"复制代码
toString()
let age = 11; let ageAsString = age.toString() // 字符串"11" let found = true let foundAsString = found.toString() // 字符串"true"复制代码
用加号操作符加上空字符串
字符串调用toString(),返回自己的一个副本
模板字面量
`` 反引号,可以保留换行符,可以跨行定义字符
定义模板方便
字符串插值
可以在一个连续定义中插入一个或者多个值
是一种特殊的语法表达式,求值后得到的是字符串
写法
${}
插入的值都会使用toString()强制转型为字符串插值内可以调用函数和方法
模板字面量标签函数
原始字符串数组 第一个参数总是接收这个插值左右两边的字符,并存入数组
每个表达式的求值结果 有多少个插值就有多少个参数可以用剩余参数
let a = 6; let b = 9; function simpleTag(strings, aValExpression, bValExpression, sumExpression) { console.log(strings); // ["", " + ", " = ", ""] console.log(aValExpression); // 6 console.log(bValExpression); // 9 console.log(sumExpression); // 15 return 'foobar'; } let taggedResult = simpleTag`${ a } + ${ b } = ${ a + b }`;复制代码
通过标签函数可以自定义插值行为
标签函数接受被插值记号分割后的模板和表达式求值的结果
标签函数本身是一个常规函数,通过前缀到模板字面量来应用自定义行为
标签函数接受参数为原始字符串数组和每个表达式的求值结果
标签函数返回值是自定义模板字面量后字符串
例子
// 把目标字符串中的数值格式化为美元 function format(strings,...values){ return strings.reduce((s,v,idx)=>{ if(idx>0){ const prev=values[idx-1] if(typeof prev==='number'){ s+=`$${prev.toFixed(2)}` }else{ s+=prev } } return s+v },'') } const item='orange' const price=3.5554 const text=format`the ${item}'s price is ${price}` console.log(text) // the orange's price is $3.56复制代码
Symbol
es6 新增基本数据类型,符合是原始值,符合实例是唯一、不可变的。符合用途确保对象属性使用唯一标识符,且不会发生属性冲突
symbol基本使用
let mySymbol = Symbol() let myWrappedSymbol = Object(mySymbol)
使用Symbol()函数初始化,typeof会返回symbol类型
调用时可以传入一个字符串参数作为描述,以方便将来通过这个字符串调用代码
symbol没有字面量,只要创建symbol实例作为object的新属性,就可以保证不会覆盖已经有的对象
symbol函数不能用new关键字作为构造函数使用,let mySymbol = new Symbol() // TypeError: Symbol is not a constructor
使用symbol包装对象
例子let otherGenericSymbol = Symbol() let fooSymbol = Symbol('foo') let otherFooSymbol = Symbol('foo') console.log(genericSymbol == otherGenericSymbol) // false console.log(fooSymbol == otherFooSymbol) // false
let sym = Symbol() console.log(typeof sym) // symbol
let genericSymbol = Symbol()
使用全局符合注册表
参数必须是symbol,
返回全局符合对应的字符串,如没有则是undefined
let localSymbol = Symbol('foo') let globalSymbol = Symbol.for('foo') console.log(localSymbol === globalSymbol); // false
let fooGlobalSymbol = Symbol.for('foo') // 创建新符号 let otherFooGlobalSymbol = Symbol.for('foo') // 重用已有符号
使用Symbol.for() 创建共享符号
过程:搜索全局符号注册表,(幂等操作),若存在,就返回符号实例,不存在,创建一个新符号并添加注册到注册表中
使用Symbol().for()注册的和Symbol()函数注册的不相同
全局注册表中的符号必须是string,任何参数通过Symbol.for(),都会转换为string
Symbol.keyFor()查询全局注册表
// 创建全局符号 let s = Symbol.for('foo') console.log(Symbol.keyFor(s)) // foo // 创建普通符号 let s2 = Symbol('bar') console.log(Symbol.keyFor(s2) // undefined //传给Symbol.keyFor()的不是符号 Symbol.keyFor(123); // TypeError: 123 is not a symbol复制代码
使用符号作为属性
Object.defineProperty()
obj:要定义或者修改的对象 props: 属性名 descriptor: 属性描述 descriptor: { configurable: false // 可配置性 enumerable: false // 可枚举性 writable: true // 可修改性 value: '' // 定义属性值 方式一 get() { // 定义属性值 方式二 }, set() { // 定义属性值 方式二 } }复制代码
方式二与方式一不能同时出现 3. 例子
let s1 = Symbol('foo'), s2 = Symbol('bar'), s3 = Symbol('baz'), s4 = Symbol('qux'); let o = { [s1]: 'foo val' }; let a = Object.defineProperty(o, s2, {value: 'bar val'}) console.log(o) // {Symbol(foo): 'foo val', Symbol(bar): 'bar val'} console.log(a) // {Symbol(foo): 'foo val', Symbol(bar): 'bar val'}复制代码
Object.defineProperties()
obj:要定义或者修改的对象 descriptor:属性集合对象 descriptor:{ name: { value: 'key', configurable: false // 可配置性 enumerable: false // 可枚举性 writable: true // 可修改性 } }复制代码
// 例子 let s1 = Symbol('foo'), s2 = Symbol('bar'), s3 = Symbol('baz'), s4 = Symbol('qux'); let o = { [s1]: 'foo val' }; let b = Object.defineProperties(o, { [s3]: {value: 'baz val'}, [s4]: {value: 'qux val'} }) console.log(o) // {Symbol(foo): 'foo val', Symbol(baz): 'baz val', Symbol(qux): 'qux val'} console.log(b) // {Symbol(foo): 'foo val', Symbol(baz): 'baz val', Symbol(qux): 'qux val'}复制代码
Object.getOwnPropertyNames()
Object.getOwnPropertySymbols()
Object.getOwnPropertyDescriptors()
Reflect.ownKeys()
例子
let s1 = Symbol('foo'), s2 = Symbol('bar'); let o = { [s1]: 'foo val', [s2]: 'bar val', baz: 'baz val', qux: 'qux val' }; console.log(Object.getOwnPropertySymbols(o)); // [Symbol(foo), Symbol(bar)] console.log(Object.getOwnPropertyNames(o)); // ["baz", "qux"] console.log(Object.getOwnPropertyDescriptors(o)); // {baz: {...}, qux: {...}, Symbol(foo): {...}, Symbol(bar): {...}} // {baz: {configurable: true, enumerable: true, value: "baz val", writable: true}} console.log(Reflect.ownKeys(o)); // ["baz", "qux", Symbol(foo), Symbol(bar)]复制代码
查找没有显示保存属性的引用值时,要循环去寻找
let o = { [Symbol('foo')]: 'foo val', [Symbol('bar')]: 'bar val' }; console.log(o); // {Symbol(foo): "foo val", Symbol(bar): "bar val"} let barSymbol = Object.getOwnPropertySymbols(o) .find((symbol) => symbol.toString().match(/bar/)); console.log(barSymbol); // Symbol(bar)复制代码
凡是可以用字符串和数值作为属性的地方。也可以使用符合
对象字面量属性和Object.defineProperty()和Object.defineProperties()定义属性
添加、修改对象属性,通过属性特征描述符可以控制属性的可配置性,可枚举性,可修改性
Object.defineProperty(obj, props, descriptor),返回修改的目标对象
一次性定义多个属性
Object.defineProperty(obj, descriptor),返回修改的目标对象,两个参数
返回对象实例的常规属性数组
返回对象实例的符号属性数组
返回同时包含常规和符号属性描述符的对象
返回两种类型的键
常用内置符号
es6引入了常用的内置符号,暴露语言内部行为,可以让开发者直接访问、重新或者模拟这些行为
都是一symbol工厂函数字符串属性的形式存在
用途之一重新定义,改变原生结构
是全局函数Symbol的普通字符串属性,指向一个符号的实例
内置符号属性都是不可写、不可枚举、不可配置的
引用符号的前缀是@@ @@iterator 指的就是Symbol.iterator
symbol.asyncIterator
实现异步迭代器API的函数
有for-await-of 语句使用
例子
class Emitter { constructor(max) { this.max = max; this.asyncIdx = 0; } async *[Symbol.asyncIterator]() { while(this.asyncIdx < this.max) { yield new Promise((resolve) => resolve(this.asyncIdx++)); } } } async function asyncCount() { let emitter = new Emitter(5); for await(const x of emitter) { console.log(x); } } asyncCount(); // 0 // 1 // 2 // 3 // 4复制代码
Symbol.hasInstance
以Symbol.hasInstance为key的函数也会执行,区别是操作数对调
例子
function Foo() {} let f = new Foo(); console.log(Foo[Symbol.hasInstance](f)); // true复制代码
属性定义在Function原型上,因此默认所有的函数和类上都能调用。
instanceof会在原型上寻找这个属性定义,可以在继承的类上通过静态方法重新定义
例子
class Bar {} class Baz extends Bar { static [Symbol.hasInstance]() { return false; } } let b = new Baz(); console.log(Bar[Symbol.hasInstance](b)); // true console.log(b instanceof Bar); // true console.log(Baz[Symbol.hasInstance](b)); // false console.log(b instanceof Baz); // false复制代码
例子
function Foo() {} let f = new Foo(); console.log(f instanceof Foo);复制代码
instanceof 确认一个对象实例的原型链上是否有原型
ES6中 instanceof 操作符使用 Symbol.hasInstance函数确认关系
Symbol.isConcatSpreadable
例子
类数组对象
讲类数组对象转换为数组
例子
例子
通过Symbol.isConcatSpreadable的值(false、true)修改ES6concat()方法
为false、假值的时候整个对象被加到数组末尾
let initial = ['foo']; let array = ['bar']; console.log(initial.concat(array)); // ['foo', 'bar'] console.log(array[Symbol.isConcatSpreadable]) // undefined array[Symbol.isConcatSpreadable] = false console.log(initial.concat(array)); // ['foo', Array(1)]复制代码
为true、真值把这个类数组对象打平到数组实例
let say = function () { console.log(arguments) // 类数组对象 不能用数组的方法,但是可以用索引来访问。存在length } say(1, 2) // 结构为 0: 1 1: 2 length: 2 {0: 1, 1: 2, length: 2} 如果一个普通的对象加上一个 length 属性就可以变成一个类数组对象。 {length: 1, value: 1, 0: 3}复制代码
let say = function () { console.log(Array.from(arguments)) // [1, 2] } say(1, 2)复制代码
let initial = ['foo']; let arrayLikeObject = { length: 1, 0: 'baz' }; console.log(initial.concat(arrayLikeObject)); // ['foo', {…}] console.log(arrayLikeObject[Symbol.isConcatSpreadable]); // undefined arrayLikeObject[Symbol.isConcatSpreadable] = true; console.log(initial.concat(arrayLikeObject)); // ['foo', 'baz']复制代码
不是类数组对象的在设置为true时会被忽略
let initial = ['foo']; let otherObject = new Set().add('qux'); console.log(initial.concat(otherObject)); // ['foo', Set(1)] console.log(otherObject[Symbol.isConcatSpreadable]); // undefined otherObject[Symbol.isConcatSpreadable] = true; console.log(initial.concat(otherObject)); // ['foo']复制代码
Symbol.iterator
表示实现迭代器API的函数
有for-of语句使用
默认这个函数会返回一个实现迭代器API的对象,返回的这个对象是实现该API的generator
例子
class Emitter { constructor(max) { this.max = max; this.idx = 0; } *[Symbol.iterator]() { while(this.idx < this.max) { yield this.idx++; } } } function count () { const emitter = new Emitter(5); for (const x of emitter) { console.log(x); } } count() // 0, 1, 2, 3, 4复制代码
Symbol.match
class FooMatcher { static [Symbol.match](target) { return target.includes('foo'); } } console.log('foobar'.match(FooMatcher)); // true console.log('barbaz'.match(FooMatcher)); // false class StringMatcher { constructor(str) { this.str = str; } [Symbol.match](target) { return target.includes(this.str); } } console.log('foobar'.match(new StringMatcher('foo'))); // true console.log('barbaz'.match(new StringMatcher('qux'))); // false复制代码
表示一个正则表达式方法,用正则表达式去匹配字符串
由String.prototype.macth()调用
参数是一个正则表达式,若不是正则,会转换成正则对象
可以自定义Symbol.match函数
例子
Symbol.replace
class FooReplacer { static [Symbol.replace](target, replacement) { return target.split('foo').join(replacement); } } console.log('barfoobaz'.replace(FooReplacer, 'qux')); // "barquxbaz" class StringReplacer { constructor(str) { this.str = str; } [Symbol.replace](target, replacement) { return target.split(this.str).join(replacement); } } console.log('barfoobaz'.replace(new StringReplacer('foo'), 'qux')); // "barquxbaz"复制代码
替换一个字符串中匹配的子串
由String.prototype.replace()调用
参数是一个正则表达式,若不是正则,会转换成正则对象
可以自定义Symbol.replace函数
Symbol.search
class FooSearcher { static [Symbol.search](target) { return target.indexOf('foo'); } } console.log('foobar'.search(FooSearcher)); // 0 console.log('barfoo'.search(FooSearcher)); // 3 console.log('barbaz'.search(FooSearcher)); // -1 class StringSearcher { constructor(str) { this.str = str; } [Symbol.search](target) { return target.indexOf(this.str); } } console.log('foobar'.search(new StringSearcher('foo'))); // 0 console.log('barfoo'.search(new StringSearcher('foo'))); // 3 console.log('barbaz'.search(new StringSearcher('qux'))); // -1复制代码
返回匹配字符串中子串的下标
由String.prototype.search()调用
参数是一个正则表达式,若不是正则,会转换成正则对象
可以自定义Symbol.search函数
Symbol.species
class Bar extends Array {} let bar = new Bar(); console.log(bar instanceof Array); // true console.log(bar instanceof Bar); // true bar = bar.concat('bar'); console.log(bar instanceof Array); // true console.log(bar instanceof Bar); // true class Baz extends Array { // 覆盖 species 到父级的 Array 构造函数上 static get [Symbol.species]() { return Array; } } let baz = new Baz(); console.log(baz instanceof Array); // true console.log(baz instanceof Baz); // true baz = baz.concat('baz'); console.log(baz instanceof Array); // true console.log(baz instanceof Baz); // false复制代码
是一个函数值的属性,被构造函数用以创建派生对象
用Symbol.species 定义静态的获取器(getter)方法, 可以修改子类覆盖对象的默认构造函数
Symbol.split
class FooSplitter { static [Symbol.split](target) { return target.split('foo'); } } console.log('barfoobaz'.split(FooSplitter)); // ["bar", "baz"] class StringSplitter { constructor(str) { this.str = str; } [Symbol.split](target) { return target.split(this.str); } } console.log('barfoobaz'.split(new StringSplitter('foo'))); // ["bar", "baz"]复制代码
在匹配正则表达式的索引位置拆分字符串
String.prototype.split()方法使用
参数是一个正则表达式,若不是正则,会转换成正则对象
可以自定义Symbol.split函数
Symbol.toPrimitive
class Foo {} let foo = new Foo(); console.log(3 + foo); // "3[object Object]" console.log(3 - foo); // NaN console.log(String(foo)); // "[object Object]" class Bar { constructor() { this[Symbol.toPrimitive] = function(hint) { // hint 为number、string、default switch (hint) { case 'number': return 3; case 'string': return 'string bar'; case 'default': default: return 'default bar'; } } } } let bar = new Bar() console.log(3 + bar); // "3default bar“ console.log(3 - bar); // 0 console.log(3 - bar); // string bar复制代码
是一个方法,将对象转换为相应的原始值
由ToPrimitive 抽象操作使用
自定义的对象,实例可以通过Symbol.toPrimitive,定义一个函数改变默认行为
Symbol.toStringTag
let s = new Set() console.log(s) // Set(0) {} console.log(s.toString()) // [object Set] console.log(s[Symbol.toStringTag]) // Set class Foo = {} let foo= new Foo() console.log(foo); // Foo {} console.log(foo.toString()); // [object Object] console.log(foo[Symbol.toStringTag]) // undefined class Bar { constructor() { this[Symbol.toSrtingTag] = 'Bar' } } let bar = new Bar() console.log(bar); // Bar {} console.log(bar.toString()); // [object Bar] console.log(bar[Symbol.toStringTag]) // Bar复制代码
通常作为对象的属性key使用
对应的数值应该为string类型,用来表示该对象的自定义类型标签
通常由内置的 Object.prototype.toString() 调用,把它包含在自己的返回值
Object.prototype.toString() 调用时,会寻找symbol.toStringTag指定的实例标识符。默认为Object
自定义类实例需要明确定义
Symbol.unscopables
let o = { foo: 'bar'} with(o) { console.log(foo) // bar } o[Symbol.unscopables] = { foo: true } with(o) { console.log(foo) // foo is not defined }复制代码
指用于指定对象值,其对象自身和继承的从关联对象的 with 环境绑定中排除的属性名称
表示一个对象所有的以及集成的属性,从关联对象的with环境绑定中排除
不推荐使用
Object
一组数据和功能的集合
通过创建object类型的实例来创建自己的对象
let o = new Object()复制代码
每个object的实例都有下面的属性和方法
返回对象对应的字符串、数值、布尔值
返回对象的字符串表示
与toLocaleString区别
返回对象的字符串表示,反应对象所在的本地化执行环境
主要用于将数组 Number对象或Date对象转换为本地格式的字符串
判断当前给的属性可不可以使用for-in枚举
判断一个对象是否存在另一个对象的原型连上
判断当前对象实例(不是原型)上,是否存在给定的属性
参数必须是string或者symbol
用于创建和初始化class创建的对象的特殊方法
constructor
class Bar { constructor() { this.name = 'bar' } } const bar = new Bar() console.log(bar.name) // 'bar'复制代码
hasOwnProperty
const foo = {} foo.name = 'foo' console.log(foo.hasOwnProperty(name)) // true console,log(foo.hasOwnProperty(sex)) // false复制代码
isPrototypeOf
function Foo() {} function Bar() {} Bar.prototype = Object.create(Foo.prototype) const bar = new Bar() Bar.prototype.isPrototypeOf(bar) // true Foo.prototype.isPrototypeOf(bar) // true复制代码
propertyIsEnumerable
const o = {} const a = [] o.name = 'object' a[0] = 'array' console.log(a.propertyIsEnumerable(0)) // true console.log(o.propertyIsEnumerable('name')) // true console.log(a.propertyIsEnumerable('length)) // false console.log(o.isPrototypeOf('isPrototypeOf')) // false复制代码
toLocaleString
toString
const a = 123 console.log(a.toString()) // '123' console.log(a.toLocaleString()) '123' const b = 1234567 console.log(b.toString()) // '1234567' console.log(b.toLocaleString()) '1,234,567' const time = new Date() console.log(time.toString()) // Wed Dec 29 2021 12:59:04 GMT+0800 (中国标准时间) console.log(time.toLocaleString()) // 2021/12/29 下午12:59:04复制代码
valueOf
const num = 123456 console.log(num.valueOf()) // 123456 const array = ["ABC", true, 12, -5] console.log(array.valueOf() === array) // true const date = new Date(2021, 12, 29, 13, 11, 59, 230) console.log(date.valueOf()) // 1643433119230
作者:夏呼呼
链接:https://juejin.cn/post/7047001303192436767