阅读 203

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()

    1. let num1 = parseInt("1234blue") // 1234

    2. let num2 = parseInt("") // NaN

    3. let num3 = parseInt("0xA") // 10,解释为十六进制整数

    4. let num4 = parseInt(22.5) // 22

    5. let num5 = parseInt("70") // 70,解释为十进制值

    6. let num6 = parseInt("0xf")// 15,解释为十六进制整数

    7. let num1 = parseInt("10", 2) // 2,按二进制解析

    8. let num2 = parseInt("10", 8) // 8,按八进制解析

    9. let num3 = parseInt("10", 10) // 10,按十进制解析

    10. let num4 = parseInt("10", 16) // 16,按十六进制解析

    1. 字符串类型数值,包含'-','+',直接转为10进制,会自动忽略0,Number('01) // 1, Number('-00001') // -1

    2. 有效的字符串浮点类型数值,会直接转换相应的浮点数,会忽略0

    3. 包含有效的十六进制格式。'0xf',转换该十六进制对应的十进制的整数值

    4. 空字符串,转0

    5. 其余字符串会转为 NaN

String

  • 声明 单引号'', 双引号"", 反引号``, 以什么引号开头就要以什么引号结束

    1. let firstName = "John"

    2. let firstName = 'John'

    3. let firstName = John

  • 字符字面量

    • 含有双字节字符,length不准确

    • 用来表示非打印字符或其他用途字符,可以在字符串的任意位置

    • 常见字面量

    • length 属性

    1. \n 换行

    2. \t 制表

    3. \b 退格

    4. \r 回车

    5. \f 换页

    6. \ 反斜杠(\)

    7. ' 单引号(')

    8. " 双引号(")

    9. ` 反引号(`)

    10. \xnn 以十六进制编码nn表示的字符(n表示十六进制数字0~F),'\x42' 表示 'A'

    11. \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"复制代码
    • 用加号操作符加上空字符串

    1. 字符串调用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

    1. let sym = Symbol() console.log(typeof sym) // symbol

    2. 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()定义属性

    1. 添加、修改对象属性,通过属性特征描述符可以控制属性的可配置性,可枚举性,可修改性

    2. Object.defineProperty(obj, props, descriptor),返回修改的目标对象

    1. 一次性定义多个属性

    2. Object.defineProperty(obj, descriptor),返回修改的目标对象,两个参数

    1. 返回对象实例的常规属性数组

    1. 返回对象实例的符号属性数组

    1. 返回同时包含常规和符号属性描述符的对象

    1. 返回两种类型的键

  • 常用内置符号

    • 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


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐