迅闻网
让更多人看到你

javascript类型(JavaScript常用数据类型)

  javascript类型

一、JavaScript中的类型
JavaScript中的类型能够分为根本数据类型和引证类型两种:
根本类型值:指的是保存在栈内存中的简略数据段;
引证类型值:指的是那些保存在堆内存中的目标,意思是,栈内存中保存的实践上仅仅一个指针,这个指针指向内存堆中实践的值;
JavaScript中的的每一个值都归于某一种数据类型。
根本数据类型定义是按值拜访,可操作保存在变量中的实践的值。根本类型值指的是简略的数据段。JavaScript语言规定了6种根本数据类型。数据类型广泛用于变量、函数参数、表达式、函数回来值等场合。依据最新的语言规范,这6种数据类型是:Undefined、Null、Boolean、String、Number、Symbol。
引证类型:当仿制保存着目标的某个变量时,操作的是目标的引证,但在为目标增加特点时,操作的是实践的目标。引证类型值指那些可能为多个值构成的目标。引证类型有这几种:Object、Array、RegExp、Date、Function、特别的根本包装类型(String、Number、Boolean)以及单体内置目标(Global、Math)。其间Object是JavaScript中最杂乱的类型,也是JavaScript的核心机制之一。Object表明目标的意思,它是全部有形和无形物体的总称。
二、根本类型值和引证类型值的区别
1、引证类型值可增加特点和办法,而根本类型值则不能够。
//为引证类型值增加特点
varp=newObject();
p.age=11;
console.log(p.age);//11
//为根本类型值增加特点
varname=’a’;
name.age=11;
console.log(name.age);//undefined
2、在仿制变量值时,根本类型会在变量目标上创立一个新值,再仿制给新变量。尔后,两个变量的任何操作都不会影响到对方。而引证类型在创立一个目标类型时,核算机会在内存中开辟一个空间来寄存值,咱们要找到这个空间,需求知道这个空间的地址,变量寄存的便是这个地址,仿制变量时其实便是将地址仿制了一份给新变量,两个变量的值都指向存储在堆中的一个目标,也便是说,其实他们引证了同一个目标,改变其间一个变量就会影响到另一个变量。
示例:
//根本类型值
vara=’a’;
varb=a;
a=’b’;
console.log(b);//a
//引证类型值,以数组为例
//1.对其间一个变量直接赋值不会影响到另一个变量(并未操作引证的目标)
vara=[1,2,3];
varb=a;
a=[1,2,3,4];
console.log(a);//1,2,3,4
console.log(b);//1,2,3
//2.运用push(操作了引证的目标)
vara=[1,2,3];
varb=a;
a.push(4);
console.log(a);//1,2,3,4
console.log(b);//1,2,3,4
三、类型的检测
1、typeof
typeof是一个一元运算,放在一个运管用之前,运管用可所以任意类型。其回来值是一个字符串,该字符串说明运管用的类型。
示例:
varnum=1;
vara=’a’;
varb;
varflag=true;
varo=null;
varfn=function(){};
varrg=/hello/;
console.log(typeofnum);//number
console.log(typeofa);//string
console.log(typeofb);//undefined
console.log(typeofflag);//boolean
console.log(typeofo);//object
console.log(typeoffn);//function
console.log(typeofrg);//object(sarari5、chrome7前回来function)
事实上,“类型”在JavaScript中是一个有争议的概念。一方面,规范中规定了运行时数据类型;另一方面,JS语言中供给了typeof这样的运算,用来回来操作数的类型,但typeof的运算结果,与运行时类型的规定有许多不一致的地方。咱们能够看下表来对照一下。

java
总结:
typeof关于根本类型来说,除了null都能够显示正确类型
typeof关于引证类型来说,除了函数都会显示object(判别数组能够运用Array.isArray()办法)
注:运用未声明的变量只要一种状况不报错便是
typeof(a);//undefined
1
这是由于typeof回来的是一个字符串
typeof(typeof(a));//string
1
其他示例:
typeof(undefined);//undefined
typeof(NaN);//number
typeof(null);//object
vara=”123abc”;
typeof(+a);//numberr
typeof(!!a);//boolean
typeof(a+””);//string
2、instanceof
用来测验一个目标在其原型链中是否存在一个结构函数的prototype特点。
语法:objectinstanceofconstructor
参数:object(要检测的目标.)constructor(某个结构函数)
描述:instanceof运算符用来检测constructor.prototype是否存在于参数object的原型链上。
示例
vara=newArray();
console.log(ainstanceofArray);//true
console.log(ainstanceofObject);//true,这是由于Array是object的子类。
functiontest(){};
vara=newtest();
console.log(ainstanceoftest)//true
instanceof的首要作用是在承继联系中用来判别一个实例是否归于它的父类型,其优点在于即使在多层承继联系中,instanceof运算符相同适用,示例:
functionFoo(){}
Foo.prototype=newAoo();//JavaScript原型承继
varfoo=newFoo();
console.log(fooinstanceofFoo);//true
console.log(fooinstanceofAoo);//true
综上所述,无论是typeof仍是instanceof都不能精确判别出正确的类型,因而在需求判别类型时咱们仍是需求结合场景选择运用。
四、为什么给目标增加的办法能够用在根本类型上?
在JavaScript的学习过程中咱们往往会产生一个疑问,为什么给目标增加的办法能用在根本类型上?
实践上这是由于在JavaScript中,目标的定义是“特点的调集”。特点分为数据特点和拜访器特点,二者都是key-value结构,key可所以字符串或许Symbol类型。说到目标,咱们必需求说到一个概念:类。由于C++和Java的成功,在这两门语言中,每个类都是一个类型,二者简直等同,以至于许多人常常会把JavaScript的“类”与类型混淆。事实上,JavaScript中的“类”仅仅是运行时目标的一个私有特点,而JavaScript中是无法自定义类型的。JavaScript中的几个根本类型,都在目标类型中有一个“亲属”。它们是:Number、String、Boolean、Symbol。所以,咱们必须认识到3与newNumber(3)是完全不同的值,它们一个是Number类型,一个是目标类型。Number、String和Boolean,三个结构器是两用的,当跟new调配时,它们产生目标,当直接调用时,它们表明强制类型转化。Symbol函数比较特别,直接用new调用它会抛出过错,但它仍然是Symbol目标的结构器。
JavaScript语言规划上企图模糊目标和根本类型之间的联系,咱们日常代码能够把目标的办法在根本类型上运用,比方:
console.log(“abc”.charAt(0));//a
1
甚至咱们在原型上增加办法,都能够应用于根本类型,比方以下代码,在Symbol原型上增加了hello办法,在任何Symbol类型变量都能够调用。
Symbol.prototype.hello=()=>console.log(“hello”);
vara=Symbol(“a”);
console.log(typeofa);//symbol,a并非目标
a.hello();//hello,有效
所以这个问题的答案便是.运算符供给了装箱操作,它会依据根底类型结构一个暂时目标,使得咱们能在根底类型上调用对应目标的办法。
以下面例子为例:
varup=”heisasuperman”;
varoutput=up.charAt(5);
console.log(output);//a
当履行
varoutput=up.charAt(5);
1
这个步骤的时分后台会这样
varup=newString(“heisasuperman”);
1
找到对应的包装目标,包装成一个和up值持平的目标回来
varoutput=up.charAt(5);//调用办法回来给output
up=null;//然后毁掉
1
2
同理,数字、布尔值在读取特点的时分也能够经过自己的结构函数来创立自己的一个暂时目标,并像目标一样(便是一个目标)引证各自的特点,所以,字符串、数字、布尔值都能够当作是目标,留意,这里是当作目标,他们并不是真实的目标,也便是严厉来说,它们并不是目标,由于目标是可变的,能够修正特点,而原始值是不行变的是不行修正的(看下面)
varb=”abcdefg”;
console.log(b.toUpperCase());//ABCDEFG
console.log(b);//abcdefg
它仅仅回来一个变成大写的副本没有改变原始的变量,并且不能在原始数据类型上增加特点和办法。由于创立的仅仅一个暂时目标,写的特点和办法只存在于暂时目标上,引证完后随即毁掉。
这儿需求留意null和undefined,首先是null它是一个关键字,表明为“空”并且
console.log(typeofnull);//object
1
由此可见它是一个目标,可是它仅仅指向一个空目标的引证。
然后是undefined,undefined是另一个表明“空值”特别值,它表明未定义,当咱们对变量只声明没有初始化时(赋值),输出为undefined,当咱们引证一个不存在的特点时,输出也为undefined,可是请留意它并不是一个关键字,它是一个变量,并且是一个全局变量,咱们能够验证一下:
console.log(undefinedinwindow);//true
1
并且
console.log(typeofundefined);//undefined
1
这严厉标明undefined是这个类型的仅有成员,除了undefined,JavaScript里边其他全部的都能够看作是目标。
五、装箱转化与拆箱转化
1、装箱转化
每一种根本类型Number、String、Boolean、Symbol在目标中都有对应的类,所谓装箱转化,正是把根本类型转化为对应的目标,它是类型转化中一种相当重要的种类。
咱们都知道全局的Symbol函数无法运用new来调用,但咱们仍能够运用装箱机制来得到一个Symbol目标,咱们能够运用一个函数的call办法来逼迫产生装箱。咱们定义一个函数,函数里边只要returnthis,然后咱们调用函数的call办法到一个Symbol类型的值上,这样就会产生一个symbolObject。咱们能够用console.log看一下这个东西的typeof,它的值是object,咱们运用symbolObjectinstanceof能够看到,它是Symbol这个类的实例,咱们找它的constructor也是等于Symbol的,所以咱们无论从哪个视点看,它都是Symbol装箱过的目标:
varsymbolObject=(function(){returnthis;}).call(Symbol(“a”));
console.log(typeofsymbolObject);//object
console.log(symbolObjectinstanceofSymbol);//true
console.log(symbolObject.constructor==Symbol);//true
装箱机制会频频产生暂时目标,在一些对功能要求较高的场景下,咱们应该尽量防止对根本类型做装箱转化。运用内置的Object函数,咱们能够在JavaScript代码中显式调用装箱才能。
varsymbolObject=Object(Symbol(“a”));
console.log(typeofsymbolObject);//object
console.log(symbolObjectinstanceofSymbol);//true
console.log(symbolObject.constructor==Symbol);//true
每一类装箱目标皆有私有的Class特点,这些特点能够用Object.prototype.toString获取:
varsymbolObject=Object(Symbol(“a”));
console.log(Object.prototype.toString.call(symbolObject));//[objectSymbol]
1
2
在JavaScript中,没有任何办法能够更改私有的Class特点,因而Object.prototype.toString是能够精确辨认目标对应的根本类型的办法,它比instanceof愈加精确。但需求留意的是,call自身会产生装箱操作,所以需求合作typeof来区分根本类型仍是目标类型。
2、拆箱转化
在JavaScript规范中,规定了ToPrimitive函数,它是目标类型到根本类型的转化(即,拆箱转化)。目标到String和Number的转化都遵从“先拆箱再转化”的规矩。经过拆箱转化,把目标变成根本类型,再从根本类型转化为对应的String或许Number。
拆箱转化会测验调用valueOf和toString来取得拆箱后的根本类型。假如valueOf和toString都不存在,或许没有回来根本类型,则会产生类型过错TypeError。
varo={
valueOf:()=>{console.log(“valueOf”);return{}},
toString:()=>{console.log(“toString”);return{}}
}
o*2
//valueOf
//toString
//TypeError
咱们定义了一个目标o,o有valueOf和toString两个办法,这两个办法都回来一个目标,然后咱们进行o*2这个运算的时分,你会看见先履行了valueOf,接下来是toString,最后抛出了一个TypeError,这就说明晰这个拆箱转化失利了。到String的拆箱转化会优先调用toString。咱们把刚才的运算换成String(o),那么你会看到调用次序就变了。
varo={
valueOf:()=>{console.log(“valueOf”);return{}},
toString:()=>{console.log(“toString”);return{}}
}
String(o)
//toString
//valueOf
//TypeError
能够看到,toString和valueOf的履行次序并不固定,而是依据某个条件来决议的,那么是依据什么呢?
每个目标都有一个Symbol.toPrimitive特点,指向一个办法。该目标被转为根本类型的值时,会调用这个办法,回来该目标对应的根本类型值。
Symbol.toPrimitive被调用时,会承受一个字符串参数,表明当时运算的形式,一共有三种形式。
Number:该场合需求转成数值
String:该场合需求转成字符串
Default:该场合能够转成数值,也能够转成字符串
示例:
letobj={
[Symbol.toPrimitive](hint){
switch(hint){
case’number’:
return123;
case’string’:
return’str’;
case’default’:
return’default’;
default:
thrownewError();
}
}
};
2*obj//246
3+obj//’3default’
obj==’default’//true
String(obj)//’str’
实践上拆箱转化的具体规矩如下:
1、查看目标中是否有用户显式定义的[Symbol.toPrimitive]办法,假如有,直接调用;
2、假如没有,则履行原内部函数ToPrimitive,然后判别传入的hint值,假如其值为string,次序调用目标的toString和valueOf办法(其间toString办法一定会履行,假如其回来一个根本类型值,则回来、终止运算,不然持续调用valueOf办法);
3、假如判别传入的hint值不为string,则就可能为number或许default了,均会次序调用目标的valueOf和toString办法(其间valueOf办法一定会履行,假如其回来一个根本类型值,则回来、终止运算,不然持续调用toString办法);
因而目标经过显式指定toPrimitiveSymbol来覆盖原有的行为,示例:
varo={
valueOf:()=>{console.log(“valueOf”);return{}},
toString:()=>{console.log(“toString”);return{}}
}
o[Symbol.toPrimitive]=()=>{
console.log(“toPrimitive”);
return”hello”
}
console.log(o+””)
//toPrimitive
//hello
注:类型转化的内部实现是经过toPrimitive(input[,PreferedType])办法进行转化的,这个办法的作用是将input转化成一个非目标类型。其间参数PreferedType是可选的,作用是指出了input等待被转成的类型,默认值为number,假如preferedType的值是“string”,那么先履行”toString”,后履行”valueOf”,不然先履行”valueOf”后履行”toString”。
六、类型转化办法
JavaScript中类型转化的根本原理便是上述的装箱转化和拆箱转化,下面咱们一同来看一下咱们平常常用的内省转化
1、显式类型转化
Number(mix):把mix转化成数字类型能够转为数字的就转化为相应的数字,不能转化的就转为NaN,其间:
Number(true)//1
Number(false)//0
Number(null)//0
Number(undefined)//NaN
parseInt(mix,radix):把mix转化成整数除了数字和能转化为数字的字符串,其他都转化为NaN,当mix为字符串时,则从第一位一直到非数字截止,即该办法能够截断,radix是将mix当作radix进制来进行转化若有小数部分则是直接去掉。
留意:
parseInt(true)//NaN;
parseInt(false)//NaN;
在把字符串转化为数字时,parseInt()能够截断,但Number()不能:
parseInt(“123qqq”)//123;
Number(“123qqq”)//NaN
parseFloat(number):转化成浮点类型,从一位开始看,到除了第一个点以外的非数字位截止。
Boolean(mix):转化为boolean类型。
String(mix):转化为字符串类型。
注:mix.toString(radix)与String(mix)用法不同,且undefined和null不能运用,radix是目标值的进制将mix转化成radix进制。
null.toString()//报错
tring(null)//”null”
例如将二进制10100转化为16进制过程是先parseInt()转化为10进制,然后在toString()转化为16进制:
varnum=10100;
vartest=parseInt(num,2);
num.toString(16);
2、隐式类型转化
isNaN():内部隐式调用Number()进行类型转化,再判别Number()回来的值是否是NaN。如:
isNaN(null)//false
isNaN(underfined)//true
++、–、+、-:内部隐式调用Number()转化后再进行相应核算。
+:当加号两头有一个是字符串的话,就会调用String,然后进行字符串的拼接。
-*/%:内部隐式调用Number()进行类型后再核算。
<><=>=:字符串和数字比会调用Number()转化为数字。
==、!=:转化规矩如下表所示:
类型1类型2转化结果
nullundefined不产生类型转化,直接回来true
null或undefined其它任何非null或undefined的类型不产生类型转化,直接回来false
NaN根本类型或引证类型false,NaN不等于任何东西,包括自身
string、number或boolean等根本类型Date等目标Date等目标产生拆箱转化
string、number或boolea等根本类型string、number或boolea等根本类型根本类型转化为数字进行比较
&&、||、!:
&&:先看第一个表达式转化成布尔值的值,假如为真,那么看第二个表达式转化为布尔值的值,。。。。顺次进行,直到碰到假;假如只要两个表达式,则会在第一个表达式转化为布尔值为真时,直接回来第二个表达式的值;不然回来第一个表达式的值进行赋值。
vara=1&&2+2;//4
varb=0&&2+2;//0
||:与&&类似,但先看第一个表达式转化为布尔值后的值,假如为真,直接回来第一个表达式的值,假如为假,则接着往下进行判别。
判别真假仅仅决议是否接着“往下走”,但回来的仍是其自身的值,而不是转化的布尔值
!:将后边的表达式转化为布尔值。

JavaScript常用数据类型

1、null类型,表示空值,定义一个空对象指针;2、undefined类型,表示未定义的值;3、number类型;4、string类型;5、boolean类型;6、object类型;7、Array类型。

未经允许不得转载:迅闻网 » javascript类型(JavaScript常用数据类型)
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!

 

迅闻网-让更多人看到你

登录/注册返回首页