《红宝书》 |原始数据类型

yfXM8J.png

相关文章:什么是引用类型

typeof操作符

判断变量的数据类型并返回字符串(主要用于判断原始数据类型):

let message="str";
console.log(typeof message);//"string"
console.log(typeof 95);//"number"

Undefined

undefined只有一个值,即undefined。当使用var或let声明变量时,只要没有初始化,该变量的值就默认为undefined:

let a
console.log(a)//"undefined"
console.log(a==undefined)//true

未初始化的变量与未定义的变量是有区别的,对于未定义的变量,会提示报错:

console.log(b)//报错

如果使用typeof,则不管是未初始化还是未定义,都会返回undefined。所以建议在声明变量的同时就要初始化,这样,返回undefined是我们就知道这个变量是没有声明,而不是声明了未初始化。

let a
console.log(typeof a)//"undefined"
console.log(typeof b)//"undefined"

Null

null只有一个值,即null。null表示一个空对象的指针,所以在定义将来要保存对象值的变量时,建议使用null来初始化。

let car=null;
console.log(typeof car)//"object"

这样,可以判断该变量是不是null来确定该变量是否后来被赋予了一个对象的引用:

if(cae!=null){
    //如果car被赋予了对象引用,执行
}

Boolean

它有两个字面量:true和false。其他类型的值也有相应布尔值的等价形式。可以通过Boolean()转型函数将其他类型的值转为布尔值:

//字符串类型
Boolean('')//false
Boolean('111')//true
//数值类型
Boolean(0)//false
Boolean(NaN)//false
Boolean(1)//true
//对象
Boolean(null)//false
Boolean({a:1})//true

Number

基本概念

Number使用IEEE 754 格式表示整数和浮点数。

  • 十进制整数

    let initNum=55
    
  • 八进制整数

    前缀为0,然后是八进制数字0~7,如果字面量中包含的数值超出了有效范围,会忽略前缀0,后面的数字会被当成十进制数。(在严格模式下无效)

    let octalnum=070 //八进制56
    let octalnum=079 //无效八进制值,当成79
    
  • 十六进制整数

    前缀0x,然后是十六进制数字0~9以及A~F

    let hexnum=0xA //十六进制10
    
  • 浮点数

    数值中必须包含小数点,而且小数点后面必须至少有一个数字。

    let floatnum=1.1
    let floatnum=0.1
    let floatnum=.1 //有效 但不推荐
    

    小数点后没有数字、数值本身就是整数的情况下,会被转化为整数:

    let floatnum=1.   //转为整数1
    let floatnum=10.0 //转为整数10
    

    对非常大或者非常小的数,浮点值可用科学计算法表示,格式是在数值后加上e + 几次幂,如下:

    let floatnum=3.125e7 //等于31250000
    

    由于舍入错误,很难测试特定的浮点值。如0.1+0.2实际上会等于0.30000000000000004,所以不建议检测特定的浮点值。

值的范围

ECMAScript可以表示的最小值保存在Number.MIN_VALUE中,最大值保存在Number.MAX_VALUE中,如果某个值超过js可以表示的范围,那么该数字会自动转化为Infinity-Infinity

NaN

Number有一个特殊的数值叫NaN,意思是Not a Number,即不是数值。用于表示要返回数值的操作失败了,比如0除以任何数都会导致错误:

console.log(0/1) //NaN
console.log(0/0) //NaN
console.log(-0/+0) //NaN

如果分子非0,分母是0,则返回Infinity-Infinity

console.log(5/0)   //Infinity
console.log(-5/0)  //-Infinity

任何涉及NaN的操作始终返回NaN

console.log(NaN/10) //NaN

NaN不等于包含NaN在内的任何值:

console.log(NaN==NaN); //false

isNaN()可以判断参数是否“不是数值”:

isNaN(NaN)    //true   不是数值
isNaN(10)     //false  是数值

//它会尝试把参数转为数值
isNaN("10")   //false  (被转化为了10,所以是数值)
isNaN(true)   //false  (被转化为了1,所以是)

//无法转换的则判定为“不是数值”
isNaN("blue") //true

数值转换

  • Number():将任何数据转为数值(转整数)
    Number(true)         //1
    Number(10)           //10
    Number(null)         //0
    Number(undefined)    //NaN
    //为字符串时:
    Number("")           //0
    Number("1")          //1
    Number("1.1")        //1.1
    Number("011")        //11   为八进制时,则转为十进制值
    Number("0xf")        //15   为十六进制时,转为与该十六进制值对应的十进制整数
    Number("hello")      //NaN  若为上述外的其他字符,返回NaN
    
  • parseInt():将字符串转为数值
    //1.为数值时:
    parseInt(1)    //1  
    parseInt(1.1)    //1 
    
    
    //2.为字符串时:
    //如果第一个字符不是数值、加号或减号,则返回NaN
    parseInt("")     //NaN
    parseInt("a")    //NaN
    //如果第一个字符是数值、加号或减号,则依次往后检测,直到字符串末尾或碰到非数值字符
    parseInt("1234b") //1234
    parseInt("22.5")  //22
    //可以识别八进制、十六进制
    parseInt("0xA")         //0
    parseInt("0xAF",16)     //175  后面的数表示进制数,防止混淆
    parseInt("AF",16)       //175  
    parseInt("AF")          //NaN
    parseInt("10",2)        //2  按二进制
    parseInt("10",8)        //8  按八进制
    parseInt("10",10)       //10 按十进制
    parseInt("10",16)       //16 按十六进制  
    
  • parseFloat():将字符串转为数值(转小数)
    //忽略字符串开头的0
    parseFloar("09")        //9
    //解析到字符串末尾或者碰到非数值字符为止,其中第一个小数点有效
    parseFloat("0.01")      //0.01
    parseFloat("0.01a")     //0.01
    parseFloat("0.01.11")   //0.01
    parseFloat("1234b")     //1234
    //检测不了十六进制 始终返回0
    parseFloat("0xA")       //0
    

String

字符串的表示

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

let str="Jack";
let str='Jack';
let str=`Jack`;

字符串拼接

+连接,拼接两个字符串。

console.log('abc'+'d') //"abcd"     如果另一个是数字,不会计算结果;
console.log('2'+1)     //"21"
console.log('2'+'1')   //"21"   

JS转义字符

转义字符主要用于表示非打印字符或其他用途字符。字符串内部如果存在特殊字符(如'",\等),需要采用\来进行转义,否则会报错:

yfbl0U.png

JS定义反斜杠加上字符可以表示字符自身:

let text='i\'am'
console.log(text)  //i'am

注意,一些字符加上反斜杠后会表示特殊字符而不是原字符本身,这些特殊转义字符被称为转义序列,具体说明如表所示:

yfbc9A.png

下面是使用换行转义字符的例子:

let text="first line\nsecond line"
console.log(text)
//first line
//second line

//它们可以放在任意位置,且作为单个字符被解释:
console.log(text.length) //3

html转义字符分成三部分:第一部分是一个&符号;第二部分是实体(Entity)名字或者是#加上实体(Entity)编号;第三部分是一个分号。比如,要显示小于号(<),就可以写 &lt; 或者 &#60;。它与JS转义字符的区别在于书写方式不一样。文章参考:https://blog.csdn.net/xinzhu1990/article/details/7032301

字符串不可变

字符串是不可变的(immutable),即一旦创建,值就不能变了。要修改某个变量的字符串值,必须先销毁原始的字符串,然后重新赋值一个新的字符串:

let lang="english"
lang="chinese" //之前的english被销毁

转化为字符串

转化为字符串的方法有两种:一种是toString(),一种是String()

  • toString():返回自身的一个副本,可以转换数值、布尔值、对象和字符串值
    let age=11;
    let ageString=age.toString() //"11"
    
    let found=true;
    let foundString=found.toString() //"true"
    
    一般情况下不接受参数。当然也可以接收一个底数作为参数,即以什么底数来输出数值的字符串表示:
    let num=10
    num.toString()   //"10"    (默认情况下返回十进制字符串表示)
    num.toString(2)  //"1010"   二进制的字符串表示
    num.toString(8)  //"12"     八进制的字符串表示
    num.toString(10) //"10"     十进制的字符串表示
    num.toString(16) //"a"      十六进制的字符串表示
    
  • String():这个方法不仅可以转换数值、布尔值、对象和字符串值, 还可以转换nullundefined,它直接返回这两个值的字面量文本:
    let value=null
    String(value)//"null"
    
    let value2=undefined
    String(value2)//"undefined"
    

模板字面量

使用模板字面量可以保留换行字符实现跨行:

//1.一般情况下通过\n换行
let str=fiist line\nsecond line;

//2.模板字符串直接换行
let str=`first
line`

console.log(str)
//first line
//second line

顾名思义,模板字面量在定义模板时特别有用:

let pageHtml=`
<div>
    <a href="#">
        jack
    </a>
</div>`

字符串插值

模板字面量最常用的特性就是支持字符串插值。

实际上模板字面量不是字符串,而是一种特殊的JavaScript表达式。模板字面量在定义时立即求值并转换为字符串实例,任何插入的变量会从离它们最近的作用域中取值。字符串插值通过在${}中使用一个JavaScript表达式实现:

let age=5;
let name='Jack';

//1.以前的字符串插值
let str=name+'is'+age+'years old.'

//2.模板字面量插值
let str=`${name} is ${age} years old.`

console.log(str)//"Jack is 5 years old."

在插值表达式中可以调用函数和方法:

function capitalize(word){
    //调用方法:toUpperCase()和slice()
    return `${word[0].toUpperCase()}${word.slice(1)}`
}

//调用函数:capitalize()
console.log(`${capitalize('hello')},${capitalize('world')}!`)    //Hello,World

toUpperCase():该方法将字符串转为大写形式并返回;
slice(开始索引,结束索引):提取某个字符串的一部分,并返回一个新的字符串。没有结束索引表示取到最后

模板字面量标签函数

标签函数可以自定义插值行为。标签函数会接收原始字符串数组对每个表达式求值的结果。下面定义一个标签函数:

//标签函数
function sumpleTag(stringArr,Expression1,Expression2,Expession3){
    console.log(stringArr)
    console.log(Expression1)
    console.log(Expression2)
    console.log(Expession3)
    return 'result'
}

只要将标签函数的函数名称放在模板字面量前面就可以使用:

let a=6;
let b=9;
sumpleTag`The result is: ${a}+${b}=${a+b}!`
//["The result is: ", "+", "=", "!"]    //原始字符串数组
//6                                      //${a}的求值的结果
//9                                      //${b}的求值的结果
//15                                     //${a+b}的求值的结果
//"result"                               //返回的结果

需要注意的是,如果模板字面量的开头和结尾没有字符串,那么会当成空字符串""处理:

sumpleTag`${a}+${b}=${a+b}`
//["", "+", "=", ""]    
//6
//9
//15
//"result"

应用:很多时候无法知道传过来的表达式参数有多少,这时可以用到argumentsarguments可以获取每个传入的参数值,它是一个伪数组:

function sumpleTag(stringArr){
    console.log(stringArr)
    for(let i=0;i<arguments.length;i++){
        console.log(arguments[i])
    }
    return result
}

或者使用rest参数(形式为“…变量名”),用于获取函数的多余参数:

function sumpleTag(stringArr,...expressions){
    console.log(stringArr)
    for(const v of expressions){
        console.log(v)
    }
    return 'result'
}

标签函数函数可以对传进来的原始字符串和表达式结果进行重整,最后返回一个新的字符串。它的一个重要应用是过滤HTML字符串,防止用户输入恶意内容:

var message = SaferHTML`<p>${sender} has sent you a message.</p>`;

function SaferHTML(templateData) {
  var s = templateData[0];
  for (var i = 1; i < arguments.length; i++) {
    var arg = String(arguments[i]); //将表达式结果转为字符串

    // 替换掉传过来的特殊字符如"&"、"<"、">"
    s += arg.replace(/&/g, "&amp;")
            .replace(/</g, "&lt;")
            .replace(/>/g, "&gt;");
    s += templateData[i];
  }
  return s;
}

上面代码中,sender变量往往是用户提供的,经过SaferHTML函数处理,里面的特殊字符都会被转义

var sender = '<script>alert("abc")</script>'; //恶意代码
var message = SaferHTML`<p>${sender} has sent you a message.</p>`;

console.log(message);
// <p>&lt;script&gt;alert("abc")&lt;/script&gt; has sent you a message.</p>

文章参考:https://www.cnblogs.com/xiaohuochai/p/7234281.html

原始字符串

使用模板字面量可以获取转义后的内容

//Unicode示例
//\u00A9 是版权符号
console.log(`\u00A9`)  // ©

如果不想获取转义后的的字符,可以使用String.raw标签函数:

console.log(String.raw`\u00A9`) //\u00A9

另外,可以通过标签函数的第一个参数(字符串数组)的.raw属性取得每个字符串的原始内容:

function printRaw(stringArr){
    console.log('实际上的')
    for(const string of stringArr){
        console.log(string)
    }
    console.log('转换后的')
    for(const rawString of stringArr.raw){
        console.log(rawString)
    }
}
printRaw`\u00A9${'split'}\n`

yfL3W9.png

Symbol

symbol也称符号,是原始值,其实例是唯一、不可变的。用途是保证对象属性使用唯一标识符,以免属性冲突。

符号实例化

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

可以给Symbol()传入参数,表示对该符号的描述,它与符号定义或标识完全无关。

let sym1=Symbol('foo')
let sym2=Symbol('foo')
console.log(sym1==sym2) //false

只要创建symbol()实例并将其作对象的新属性,就可以保证它不会覆盖已有的对象属性

全局符号注册

  • Symbol.for():全局注册符号
  • Symbol.keyFor():检查全局注册表

当许多地方需要共享和重用符号实例时,可以用Symbol.for()来注册全局符号,接收字符串作为描述,此时该描述同时是一个标识。

//全局创建新符号
let sym1=Symbol.for('foo')

//先检查全局注册表,判断是否存在对应的标识,没有则创建新实例,有则返回旧实例
let sym2=Symbol.for('foo')//这里是返回旧实例
console.log(sym1===sym2) //true

即使描述相同,全局注册的符号与Symbol()定义的符号是不相同的。

let sym1=Symbol('foo')
let sym2=Symnol.for('foo')
console.log(sym1===sym2)//false

可用Symbol.keyFor()检查全局注册表。接收符号,返回该全局符号对应的字符串键。

//1.全局符号
let sym1=Symbol.for('foo')
console.log(Symbol.keyFor(sym1)) //foo

//2.普通符号:若查询的不是全局符号,返回undefined
let sym2=Symbol('bar')
console.log(Symbol.keyFor(sym2)) //undefined

【应用】使用符号作为属性

let s1=Symbol('foo')
let s2=Symbol('bar')
let s3=Symbol('baz')
let s4=Symbol('qux')

//方式1:
let obj={
    [s1]:'fooValue'
}
//{Symbol(foo): "fooValue"}


//方式2:给已知对象添加属性
Object.defineProperty(obj,s2,{value:'barValue'})    
//{Symbol(foo): "fooValue", Symbol(bar): "barValue"}


//方式3:给已知对象添加多个属性
Object.defineProperties(obj,{
    [s3]:{value:'bazValue'},
    [s4]:{value:'quxValue'}
})    
//{Symbol(foo): "fooValue", Symbol(bar): "barValue", Symbol(baz): "bazValue", Symbol(qux): "quxValue"}
  • Object.getOwnPropertyNames():返回常规属性数组
  • Object.getOwnPropertySymbols():返回符号属性数组
  • Reflect.ownKeys():既返回常规属性也返回符号属性
  • Object.getOwnPropertyDescriptors():返回包含常规属性和符号属性的对象
let s1=Symbol('foo')
let s2=Symbol('bar')
let obj={
    [s1]:'fooValue',    //符号属性
    [s2]:'barValue',    //符号属性
    baz:'bazValue',     //常规属性
    qux:'quxValue'      //常规属性
}

Object.getOwnPropertyNames(obj)        //["baz", "qux"]
Object.getOwnPropertySymbols(obj)      //[Symbol(foo), Symbol(bar)]
Reflect.ownKeys(obj)                   // ["baz", "qux", Symbol(foo), Symbol(bar)]
Object.getOwnPropertyDescriptors(obj)  //{baz: {…}, qux: {…}, Symbol(foo): {…}, Symbol(bar): {…}}

因为符号属性是对内存中符号的一个引用,所以也可以直接创建并用做属性:

let obj={
    [Symbol('foo')]:'fooValue',
    [Symbol('bar')]:'barValue',
}
console.log(obj)    //{Symbol(foo): "fooValue", Symbol(bar): "barValue"}

常用内置符号

用于暴露语言内部行为,开发者可以直接访问、重写或模拟这些行为。它的用途就是重新定义它们,从而改变原生结构的行为。比如for-of循环会在相关对象上使用Symbol.iterator,那么就可以通过在自定义对象上重新定义Symbol.iterator的值来改变for-of在迭代该对象时的行为。

下面内容涉及原型、Generator函数、async函数、Class类、iterator,建议有了解后再阅读。

Symbol.hasInstance

一个方法,判断某个实例是否为某个构造器对象的实例,通过instanceof使用。在对象上借助Symbol.hasInstance可重新定义默认行为。

  • instanceof可以确定一个对象实例的原型链上是否有原型。
    function Foo(){} //构造器
    let f=new Foo(); //通过构造器创建实例
    console.log(f instanceof Foo)    //true,表示Foo是f的原型
    
  • Symbol.hasInstance为键的函数会执行与instanceof同样的操作。
    function Foo(){} 
    let f=new Foo(); 
    console.log(Foo[Symbol.hasInstance](f))    //true
    
  • 自定义Symbol.hasInstance行为:
    //例1
    class Array1 {
      static [Symbol.hasInstance](instance) {
        return Array.isArray(instance); //更改了默认行为,此时使用instanceof是判断该实例是否为数组。
      }
    }
    console.log([] instanceof Array1);//true
    
    //例2
    class Bar{}
    class Baz extends Bar{
      static [Symbol.hasInstance](instance) {
          return false
      }
    }
    
    let bar=new Bar()
    //Bar里面是默认行为
    console.log(Bar[Symbol.hasInstance](bar))//true
    console.log(bar instanceof Bar)//true
    
    //Baz里面是更改后的行为
    console.log(Baz[Symbol.hasInstance](bar))//false
    console.log(bar instanceof Baz)//false
    

Symbol.isConcatSpreadable

一个布尔值,判断是否可以打平数组元素,通过Array.prototype.concat()使用。在对象上借助[Symbol.isConcatSpreadable可重新定义默认行为。

concat():合并两个或多个数组,返回一个新数组。语法:旧数组.cancat(数组1,数组2...)
什么是打平?指在合并数组时,若把各数组元素拎出来合并,则为打平;否则就是不打平。下面是一个例子:

let arr1=['foo']
let arr2=['bar']
console.log(arr1.concat(arr2))    //['foo','bar'] 为打平
console.log(arr1.concat(arr2))    //['foo',Array(1)] 未被打平
  • 数组对象默认会被打平到已有数组
    let arr1=['foo']
    let arr2=['bar']
    console.log(arr1.concat(arr2))    //['foo','bar'] 
    
    //修改默认行为:
    arr2[Symbol.isConcatSpreadable]=false
    console.log(arr1.concat(arr2))    //['foo',Array(1)] 
    
  • 类数组对象默认不会被打平(指具有length属性的数组对象)
    let arr=['foo']
    let arrObj={length:1,0:'bar'}
    console.log(arr.concat(arrObj))    //['foo',{...}] 
    
    //修改默认行为:
    arrObj[Symbol.isConcatSpreadable]=true
    console.log(arr.concat(arrObj))    //['foo','bar'] 
    
  • 其他不是类数组对象默认不会被打平。如果将Symbol.isConcatSpreadable设置为true,那么该对象会被忽略。
    let arr=['foo']
    let other=new Set().add('bar')    //Set数据结构,add()表示给Set结构添加某个值,打印other:Set(1) {"bar"}
    console.log(arr.concat(other))    //['foo',Set(1)] 
    
    //修改默认行为:
    other[Symbol.isConcatSpreadable]=true
    console.log(arr.concat(other))    //['foo'] 
    

Symbol.iterator

一个方法,返回对象的默认迭代器,通过for-of使用。在对象上借助Symbol.iterator可重新定义默认行为:

class Emitter{
    constructor(max){
        this.max=max;
        this.idx=0
    }

    //修改异步迭代器的默认行为
    * [Symbol.iterator](){
        while(this.idx<this.max){
            yield this.idx++
        }
    }
}

function count(){
    let emitter=new Emitter(5)
    for await(const x of emitter){
        console.log(x)
    }
}

count()
//0
//1
//2
//3
//4

Symbol.asyncIterator

一个方法,返回对象默认的异步迭代器,通过for-await-of语句使用。在对象上借助Symbol.asyncIterator可重新定义异步迭代器行为:

//例1
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
//例2
const myAsyncIterable = {
    async* [Symbol.asyncIterator]() {
        yield "hello";
        yield "async";
        yield "iteration!";
    }
};

(async () => {
    for await (const x of myAsyncIterable) {
        console.log(x);
    }
})();
// "hello"
// "async"
// "iteration!"

Symbol.match

一个正则表达式方法,用于匹配字符串,通过String.prototype.match()方法使用。在对象上借助Symbol.match改变默认行为:

[例1]-专门匹配foo的匹配器:

class FooMatcher{
    //静态方法,可直接用类调用
    static [Symbol.match](target){
        return target.includes('foo')
    }
}
console.log('foobar'.match(FooMatcher)) //true
console.log('barbar'.match(FooMatcher)) //false

[例2]-匹配指定字符串的匹配器

class StringMatcher{
    constructor(str){
        this.str=str
    }

    //非静态方法,创建的实例会继承该方法
    [Symbol.match](target){
        return target.includes(this.str)
    }
}
console.log('foobar'.match(new StringMatcher('foo'))) //true

Symbol.replace

一个正则表达式方法,用于替换字符串,通过String.prototype.replace()方法使用。

console.log('foobarfoo'.replace(/foo/,'bar'))        

在对象上借助Symbol.replace接收两个参数,可通过其改变默认行为:

[例1]-将某个字符替换成#!@?的替换器:

class CustomReplacer {
  constructor(value) {
    this.value = value;
  }
  [Symbol.replace](string) {
    return string.replace(this.value, '#!@?');
  }
}

console.log('football'.replace(new CustomReplacer('foo'))); // "#!@?tball"

[例2]-将所以匹配的字符全部换成指定字符的替换器:

class Replacer {
  constructor(str,replacement) {
    this.str = str;
    this.replacement=replacement;
  }
  [Symbol.replace](target,replacement) {
    return target.split(this.str).join(this.replacement)
  }
}
console.log('foobarfoo'.replace(new Replacer('foo','bar'))); //barbarbar

Symbol.search

一个正则表达式方法,返回字符串中匹配正则表达式的索引,通过String.prototype.search()方法使用。

console.log('foobar'.search(/bar/))    //3

在对象上借助Symbol.search改变默认行为:

[例1]-专门查找foo的查找器:

class FooSearcher{
    static [Symbol.search](target){
        return target.indexOf('foo')
    }
}
console.log('foobar'.search(FooSearcher)) //0
console.log('barfoo'.search(FooSearcher)) //3

[例2]-查找指定字符的查找器:

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('bar'))) //0

Symbol.split

一个正则表达式方法,在匹配正则表达式的索引位置拆分字符,通过String.prototype.split()方法使用。

console.log('foobazbar'.split(/baz/))    //["foo", "bar"]

在对象上借助Symbol.split改变默认行为:
[例1]-根据foo拆分字符串的拆分器:

class FooSplitter{
    static [Symbol.split](target){
        return target.split('foo')
    }
}
console.log('barfoobaz'.split(FooSplitter))    //["bar", "baz"]

[例2]-根据指定字符拆分字符串的拆分器:

class StringSplitter{
    constructor(str) {
        this.str = str;
    }
    [Symbol.split](target){
        return target.split(this.str)
    }
}
console.log('barfoobaz'.split(new StringSplitter('foo')))    //["bar", "baz"]

更多内置符号请查看https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol

posted @ 2021-02-19 14:34  sanhuamao  阅读(134)  评论(0编辑  收藏  举报