分享更有价值
被信任是一种快乐

es6新增的js基本数据类型怎么用

文章页正文上

这篇“es6新增的js基本数据类型怎么用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“es6新增的js基本数据类型怎么用”文章吧。es6新增的基本数据类型:1、Symbol类型,表示独一无二的值,即Symbol实例是唯一、不可变的;它的产生是因为要用来唯一的标记,进而用作非字符串形式的对象属性,是确保对象属性使用唯一标识符,不会发生属性冲突的危险。2、BigInt类型,提供对任意长度整数的支持,主要是为了表达大于“2^53-1”的整数。本教程操作环境:windows7系统、ECMAScript 6版、Dell G3电脑。基本数据类型 也称为原始数据类型,包括String、Number、Boolean、undefined、null、Symbol、BigInt,其中SymbolBigInt为ES6新增。Symbol 是 ECMAScript6 中引入的一种新的数据类型,表示独一无二的值。Symbol 是原始值(基础数据类型),且 Symbol 实例是唯一、不可变的。它的产生是因为要用来唯一的标记,进而用作非字符串形式的对象属性,是确保对象属性使用唯一标识符,不会发生属性冲突的危险。在 ES6 之前,对象的键只能是字符串类型,但是这样有个问题,就是会造成键名命名冲突,后者覆盖前者,这个时候就需要一个唯一值来充当键名,Symbol 横空出世。1、概念symbol 是一种基本数据类型,Symbol()函数会返回 symbol 类型的值,该类型具有静态属性和静态方法。但是它不是构造函数,不能用 new Symbol()来创建。

letsymbol=Symbol();
typeofsymbol;//"symbol"

Symbol 作为对象属性时,当在对象内部时,必须要用方括号括起来,不用方括号括起来代表的是字符串。

lets=Symbol();
letobj={
[s]:"Jack",
};
obj[s];//"Jack"
obj.s;//undefined

而且当要取该属性的值时,不能用点运算符,因为点运算符后面同样是字符串类型。创建 Symbol 数据类型时,都是 Symbol()这么创建的,当打印出来时,都为 Symbol(),这样很难区别各个 Symbol 类型的变量是什么意思。所以在 Symbol 函数内可以接收一个字符串的参数,表示该定义 Symbol 类型变量的描述。

lets1=Symbol("a");
console.log(s1);//Symbol(a)
s1.toString();//"Symbol(a)"

如果 Symbol 类型接收的一个对象类型的话,那就会先调用其内部的 toString 方法,将其变为一个字符串,然后才生成一个 Symbol 值。

letarr=[1,2,3];
lets1=Symbol(arr);
console.log(s1);//Symbol(1,2,3)
letobj={
toString:()=>"abc",
};
lets2=Symbol(obj);
console.log(s2);//Symbol(abc)

Symbol 类型的变量是不能和其他变量参与运算的,而且其只能转为 String 类型和 Boolean 类型。

lets=Symbol();
console.log("1"+s);//TypeError:CannotconvertaSymbolvaluetoastring
s.toString();//"Symbol()"
Boolean(s);//true
Number(s);//TypeError:CannotconvertaSymbolvaluetoanumber

2、Symbol.prototype.description当给 Symbol 添加描述时,可以通过 Symbol.prototype.description 来获取该描述。

lets=Symbol("Jack");
s.description;//'Jack'

3、Symbol.for(key)和 Symbol.keyFor(sym)最开始看到这两个方法时,我以为是两个遍历的方法。Symbol.for(key):使用给定的 key 搜索现有的 symbol,如果找到则返回该 symbol。否则将使用给定的 key 在全局 symbol 注册表中创建一个新的 symbol。Symbol.keyFor(sym):从全局 symbol 注册表中,为给定的 symbol 检索一个 key。

lets1=Symbol.for("foo");
lets2=Symbol.for("foo");
s1===s2;//true

Symbol.for 会搜索有没有以该参数作为名称的 Symbol 值。如果有,就返回这个 Symbol 值,否则就新建一个以该字符串为名称的 Symbol 值,并将其注册到全局。所以由其创建的两个相同描述的值会相等。这种创建就和普通的 Symbol()有着截然不同的结果了:

lets1=Symbol("foo");
lets2=Symbol("foo");
s1===s2;//false

因为不管怎样 Symbol()返回的都是一个全新的值,换句话说 Symbol()生成的值没有注册在全局中,所以返回的值都是全新的,而 Symbol.for()会在先在全局中查找,有就返回这个值,没有则创建新的值,但新的值也是挂载在全局中的。Symbol.keyFor(sym)是在全局中查找是否有该 Symbol 值,有则返回该描述。

lets1=Symbol.for("Jack");
Symbol.keyFor(s1);//'Jack'
lets2=Symbol("Rose");
Symbol.keyFor(s2);//undefined

因为 s2 没有挂载在全局中,所以 Symbol.keyFor()找不到它,故返回 undefined。4、内置的 Symbol 属性除了定义自己使用的 Symbol 值以外,ES6 还提供了 13(有可能今后会更多 ?) 个内置的 Symbol 值,指向语言内部使用的方法。4.1 Symbol.asyncIteratorSymbol.asyncIterator 符号指定了一个对象的默认异步迭代器。如果一个对象设置了这个属性,它就是异步可迭代对象,可用于 for await…of 循环。换句话说一个异步可迭代对象内部必须有 Symbol.asyncIterator 属性。

constmyAsyncIterable=newObject();
myAsyncIterable[Symbol.asyncIterator]=asyncfunction*(){
yield"hello";
yield"async";
yield"iteration!";
};

(async()=>{
forawait(constxofmyAsyncIterable){
console.log(x);
//expectedoutput:
//"hello"
//"async"
//"iteration!"
}
})();

当执行 for await…of 时,就会执行该变量中 Symbol.asyncIterator 属性值。4.2、Symbol.hasInstanceSymbol.hasInstance 用于判断某对象是否为某构造器的实例。因此你可以用它自定义 instanceof 操作符在某个类上的行为。换句话说当判断一个实例是否为一个类的实例时,其实就是执行该类里面的 Symbol.hasInstance 属性。

classFu{
[Symbol.hasInstance](num){
returnnum===1;
}
}
1instanceofnewFu();//true
2instanceofnewFu();//false

4.3、Symbol.isConcatSpreadable内置的 Symbol.isConcatSpreadable 符号用于配置某对象作为 Array.prototype.concat()方法的参数时是否展开其数组元素。

//默认情况下
letarr=[1,2,3];
letbrr=[4,5,6];
arr.concat(brr);//[1,2,3,4,5,6]
//设置了Symbol.isConcatSpreadable后
letarr=[1,2,3];
letbrr=[4,5,6];
brr[Symbol.isConcatSpreadable]=false;
arr.concat(brr);//[1,2,3,[4,5,6]]

将数组的 Symbol.isConcatSpreadable 属性设置为 false 后,使用 concat 方法时该数据就不会展开。对于类数组而言,默认数组使用 concat 方法该类数组是不展开的,我们可以给类数组的 Symbol.isConcatSpreadable 设置为 true,这样就可以展开了,并且完成了类数组转换为数组,这样类数组转数组又多了一个方法。

//默认情况下
functionfoo(x,y){
letarr=[].concat(arguments);
console.log(arr);//[Arguments(2)]
}
foo(1,2);
//设置了Symbol.isConcatSpreadable为true后
functionfoo(x,y){
arguments[Symbol.isConcatSpreadable]=true;
letarr=[].concat(arguments);
console.log(arr);//[1,2]
}
foo(1,2);

4.4、Symbol.iteratorSymbol.iterator 为每一个对象定义了默认的迭代器。该迭代器可以被 for…of 循环使用。

constmyIterable={};
myIterable[Symbol.iterator]=function*(){
yield1;
yield2;
yield3;
};

[...myIterable];//[1,2,3]

对象进行 for…of 循环时,会调用 Symbol.iterator 方法,4.5、Symbol.matchSymbol.match 指定了匹配的是正则表达式而不是字符串。String.prototype.match() 方法会调用此函数。换句话说就是当 str.match()执行时如果该属性存在,就会返回该方法的返回值。

classfoo{
[Symbol.match](string){
returnstring;
}
}
"Jack".match(newfoo());//'Jack'

除上述之外,MDN 还提出了该属性另外一个功能:此函数还用于标识对象是否免费云主机、域名具有正则表达式的行为。比如, String.prototype.startsWith(),String.prototype.endsWith() 和 String.prototype.includes() 这些方法会检查其第一个参数是否是正则表达式,是正则表达式就抛出一个 TypeError。现在,如果 match symbol 设置为 false(或者一个 假值),就表示该对象不打算用作正则表达式对象。

"/bar/".startsWith(/bar/);//TypeError:FirstargumenttoString.prototype.startsWithmustnotbearegularexpression
//当设置为false之后
varre=/foo/;
re[Symbol.match]=false;
"/foo/".startsWith(re);//true
"/baz/".endsWith(re);//false

4.6、Symbol.matchAllSymbol.matchAll 返回一个迭代器,该迭代器根据字符串生成正则表达式的匹配项。此函数可以被 String.prototype.matchAll() 方法调用。

"abc".matchAll(/a/);
//等价于
/a/[Symbol.matchAll]("abc");

4.7、Symbol.replace

4.7、Symbol.replaceSymbol.replace 这个属性指定了当一个字符串替换所匹配字符串时所调用的方法。String.prototype.replace() 方法会调用此方法。

String.prototype.replace(searchValue,replaceValue);
//等同于
searchValue[Symbol.replace](this,replaceValue);
//例子
classReplace1{
constructor(value){
this.value=value;
}
[Symbol.replace](string){
return`s/${string}/${this.value}/g`;
}
}

console.log("foo".replace(newReplace1("bar")));//"s/foo/bar/g"

4.8、Symbol.searchSymbol.search 指定了一个搜索方法,这个方法接受用户输入的正则表达式,返回该正则表达式在字符串中匹配到的下标,这个方法由以下的方法来调用 String.prototype.search()。

String.prototype.search(regexp);
//等价于
regexp[Symbol.search](this);
//例子
classSearch2{
[Symbol.search](str){
return`${str}Word`;
}
}
"Hello".search(newSearch2());//HelloWord

4.9、Symbol.speciesSymbol.species 是个函数值属性,其被构造函数用以创建派生对象,换句话说 species 访问器属性允许子类覆盖对象的默认构造函数。我们举个例子:

//默认情况下
classMyArrayextendsArray{}
letarr=newMyArray(1,2,3);
letbrr=arr.map((item)=>item);
brrinstanceofMyArray;//true
brrinstanceofArray;//true

类 MyArray 继承于 Array,arr 为 MyArray 的实例,brr 为 arr 的衍生物,所以 brr 是 MyArray 的实例,并且由于原型链的缘故,brr 也是 Array 的实例。如果此时,我们只想让 brr 为 Array 的实例,那 Symbol.species 属性值就派上用场了。

classMyArrayextendsArray{
staticget[Symbol.species](){
returnArray;
}
}
letarr=newMyArray(1,2,3);
letbrr=arr.map((item)=>item);
brrinstanceofMyArray;//false
brrinstanceofArray;//true
//默认情况下
classMyArrayextendsArray{
staticget[Symbol.species](){
returnthis;
}
}

值得注意的是,定义 Symbol.species 属性时,前面必须声明是静态的 static 并且要运用 get 取值器。4.10、Symbol.splitSymbol.split 指向 一个正则表达式的索引处分割字符串的方法。 这个方法通过 String.prototype.split() 调用。

String.prototype.split(separator,limit);
//等价于
separator[Symbol.split](this,limit);
//例子
classSplit1{
[Symbol.split](str){
return`${str}Word`;
}
}
"Hello".split(newSplit1());//HelloWord

4.11、Symbol.toPrimitiveSymbol.toPrimitive 是一个内置的 Symbol 值,它是作为对象的函数值属性存在的,当一个对象转换为对应的原始值时,会调用此函数。该函数在调用时,会传递一个字符串参数 hint,表示要转换到的原始值的预期类型。字符串 hint 的类型有三种:’number’, ‘string’, ‘default’。

letobj=
{
[Symbol.toPrimitive](hint){
switch(hint){
case"number":
return123;
case"string":
return"123";
case"default":
return"default";
default:
thrownewError();
}
},
}+obj;//123
`${obj}`;//'123'
obj+"";//"default"

4.12、Symbol.toStringTagSymbol.toStringTag 是一个内置 symbol,它通常作为对象的属性键使用,对应的属性值应该为字符串类型,这个字符串用来表示该对象的自定义类型标签,通常只有内置的 Object.prototype.toString() 方法会去读取这个标签并把它包含在自己的返回值里。通俗点讲就是在 Object.prototype.toString()去判断自定义对象的数据类型时,返回的都是 object,可以通过这个属性来给自定义对象添加类型标签。

Object.prototype.toString.call('123');//[objectString]
...more

另外一些对象类型则不然,toString() 方法能识别它们是因为引擎为它们设置好了 toStringTag 标签:

Object.prototype.toString.call(newMap());//"[objectMap]"
Object.prototype.toString.call(function*(){});//"[objectGeneratorFunction]"
Object.prototype.toString.call(Promise.resolve());//"[objectPromise]"
...more

当我们自己定义一个类时,调用 Object.prototype.toString()时,由于没有内部定义 toStringTag 标签,所以只能返回”[object Object]”

classFoo{}
Object.prototype.toString.call(newFoo());//"[objectObject]"
//设置Symbol.toStringTag
classFoo{
get[Symbol.toStringTag](){
return"Foo";
}
}
Object.prototype.toString.call(newFoo());//"[objectFoo]"

4.13、Symbol.unscopablessSymbol.unscopables 指用于指定对象值,其对象自身和继承的从关联对象的 with 环境绑定中排除的属性名称。说白了其属性就是控制,在 with 词法环境中哪些属性会被 with 删除。

Array.prototype[Symbol.unscopabless];
//{
//copyWithin:true,
//entries:true,
//fill:true,
//find:true,
//findIndex:true,
//includes:true,
//keys:true
//}

这里简单的讲解一下 with 函数,with 主要是用来对对象取值的,举个简单的例子:

letobj={};
with(obj){
letnewa=a;
letnewb=b;
console.log(newa+newb);
}
//等价于
letnewa=obj.a;
letnewb=obj.b;
console.log(newa+newb);

with 的 优点:
当 with 传入的值非常复杂时,即当 object 为非常复杂的嵌套结构时,with 就使得代码显得非常简洁。
with 的缺点:
js 的编译器会检测 with 块中的变量是否属于 with 传入的对象, 上述例子为例,js 会检测 a 和 b 是否属于 obj 对象,这样就会的导致 with 语句的执行速度大大下降,性能比较差。回归正题,我们举个例子看一下 Symbol.unscopables 属性的作用。

letobj={
foo(){
return1;
}
}
with(obj){
foo();//1
}
//设置了Symbol.unscopables
letobj={
foo(){
return1;
},
get[Symbol.unscopables](){
return{
foo:true
}
}
}
with(obj){
foo();//UncaughtReferenceError:fooisnotdefined
}

设置后报错的原因是因为with已经将obj中的foo方法删除了。BigInt 是一种特殊的数字类型,它提供了对任意长度整数的支持。1、概述BigInt 是一个新型的内置类型,主要是为了表达大于 2^53-1 的整数。我们定义一个 BigInt 类型的数据时有两种方式,第一个是在数字后面加 n,另外一种是调用 BigInt()方法。

lettheBigInt=9007199254740991n;
letalsoHuge=BigInt(9007199254740991);//9007199254740991n

当用 typeof 对其进行类型判断时,返回的是 bigint。

lettheBigInt=9007199254740991n;
typeoftheBigInt;//bigint

2、运算BigInt 支持以下的运算符,+、*-**% ,并且支持除了>>> (无符号右移)之外的 其他位运算符。

letpreviousMaxSafe=BigInt(Number.MAX_SAFE_INTEGER);//9007199254740991n
letmaxPlusOne=previousMaxSafe+1n;//9007199254740992n
letmaxMinusOne=previousMaxSafe-1n;//9007199254740990n
letmulti=previousMaxSafe*2n;//18014398509481982n
letmod=previousMaxSafe%10n;//1n

值得注意的是,BigInt 是不支持单目+运算符的。

+previousMaxSafe;//UncaughtTypeError:CannotconvertaBigIntvaluetoanumber

主要原因还是 BigInt 无法和 Number 类型直接运算,如果想要运算的话必须在同一个类型上,但是有一点值得注意的是,当 BigInt 转为 Number 类型时,有可能会丢失精度。在比较运算符中,BigInt 和 Nunber 类型的之间不是严格相等的。

10n==10;//true
10n===10;//false

Number 和 BigInt 是可以进行比较的。

1n1;//true
2n>=2;//true

3、APIBigInt 拥有两个静态方法:BigInt.asIntN(width, bigint):将 BigInt 值转换为一个-2^width-1 与 2^width-1-1 之间的有符号整数。BigInt.asUintN(width, bigint):将一个 BigInt 值转换为 0 与 2^width-1 之间的无符号整数。这两个方法均接受两个参数,width:可存储整数的位数。bigint:要存储在指定位数上的整数。

constmax=2n**(64n-1n)-1n;
BigInt.asIntN(64,max);//9223372036854775807n

constmax=2n**64n-1n;
BigInt.asUintN(64,max);//18446744073709551615n

同时 BigInt 还拥有三个实例方法:BigInt.prototype.toLocaleString():返回此数字的 language-sensitive 形式的字符串。覆盖 Object.prototype.toLocaleString() 方法。BigInt.prototype.toString():返回以指定基数(base)表示指定数字的字符串。覆盖 Object.prototype.toString() 方法。BigInt.prototype.valueOf():返回指定对象的基元值。 覆盖 Object.prototype.valueOf() 方法。

letbigint=3500n;
bigint.toLocaleString();//"3,500"
bigint.toString();//"3500"
bigint.valueOf();//3500n

以上就是关于“es6新增的js基本数据类型怎么用”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注云技术行业资讯频道。

相关推荐: 怎么修改JS文件实现搜索框样式的美化与修改

这篇文章主要介绍了怎么修改JS文件实现搜索框样式的美化与修改的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇怎么修改JS文件实现搜索框样式的美化与修改文章都会有所收获,下面我们一起来看看吧。 定位JS文件DedeCMS 的搜索功能是…

文章页内容下
赞(0) 打赏
版权声明:本站采用知识共享、学习交流,不允许用于商业用途;文章由发布者自行承担一切责任,与本站无关。
文章页正文下
文章页评论上

云服务器、web空间可免费试用

宝塔面板主机、支持php,mysql等,SSL部署;安全高速企业专供99.999%稳定,另有高防主机、不限制内容等类型,具体可咨询QQ:360163164,Tel同微信:18905205712

主机选购导航云服务器试用

登录

找回密码

注册