故乡的景色 發表於 2019-5-4 10:06:00

javascript的数据类型检测

<p>JavaScript有两种数据类型,分别是基本数据类型和引用数据类型。其中基本数据类型包括Undefined、Null、Boolean、Number、String和Symbol(ES6新增,表示独一无二的值),而引用类型统称为Object对象、主要包括对象、数组和函数。</p>
<p><img src="https://img2018.cnblogs.com/blog/842514/201905/842514-20190503231213130-318464452.png" alt=""></p>
<p><span style="background-color: rgba(204, 255, 204, 1)"><strong>基本数据类型</strong></span></p>
<p>1.基本数据类型的值是不可变的。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> str = "abc"<span style="color: rgba(0, 0, 0, 1)">;
str[</span>0] = "d"; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 字符串是可以通过[]访问的</span>
<br>console.log(str="e"); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> e</span>
console.log(str); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> a</span>
console.log(str); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> abc</span></pre>
</div>
<p>在JavaScirpt中,数字、字符串、布尔值、Null和Undefined的值是不可改变的,就算在代码中动态地修改它的值,它的<span style="background-color: rgba(204, 255, 204, 1)">原始值</span>并不会发生改变,如果需要修改值,都是通过定义一个变量来保存这个新值,因为它的返回值就是修改后的值。</p>
<p>2.原始数据类型注解存储在栈(Stack)中的简单数据段,占据空间小,大小固定,属于被频繁使用数据,所以放入栈中存储。</p>
<p>3.值的比较可以用【==】或【===】运算符。【==】只进行值的比较,【===】不仅进行值的比较,还要进行数据类型的比较。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> num = 1; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Number类型</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> str = "1"; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> String类型</span>
<span style="color: rgba(0, 0, 0, 1)">
console.log(num </span>== str); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true,只比较值</span>
console.log(num === str); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> false,不仅比较值,还比较数据类型</span></pre>
</div>
<p><span style="background-color: rgba(204, 255, 204, 1)"><strong>引用数据类型</strong></span></p>
<p>1.引用数据类型的值是可变的。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> num = ;
num[</span>0] = "a"<span style="color: rgba(0, 0, 0, 1)">;
<br>console.log(num); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ["a", 2, 3]</span></pre>
</div>
<p>在JavaScript中,数组和对象的值是可变的,也就是说当动态修改里面的值的时候,原始的值也会发生相应的改变。</p>
<p>2.引用数据类型同时保存在栈内存和堆内存。</p>
<p>引用数据类型存储在堆(Heap)中的对象,占据空间大,大小不固定。如果存储在栈中,将会影响程序运行的性能。因此引用数据类型在栈中只存储指针,该指针指向堆中该实体的起始位置。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。</p>
<p><img src="https://img2018.cnblogs.com/blog/842514/201905/842514-20190503233516028-506242855.png" alt=""></p>
<p>3.引用数据类型比较的是引用地址。当从一个变量向另一个变量赋值引用类型的值时,同样也会将存储在变量上的对象的值赋值一份放到为新变量分配的空间中。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> obj1 = {age: 22<span style="color: rgba(0, 0, 0, 1)">};
</span><span style="color: rgba(0, 0, 255, 1)">var</span> obj2 = obj1; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 将obj1赋值给obj2,实际上是将obj1指向的内存地址赋值给obj2</span>
<span style="color: rgba(0, 0, 0, 1)">
console.log(obj1 </span>=== obj2); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true,obj1和obj2指向同一块内存空间</span>
<span style="color: rgba(0, 0, 0, 1)">
obj2.age </span>= 18; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> obj2修改属性的同时,obj1也一起发生了改变,因为它们指向同一个对象,任何修改操作都会相互影响</span>
console.log(obj1 === obj2); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true,obj1和obj2还是指向同一块内存空间</span></pre>
</div>
<p><strong><span style="background-color: rgba(204, 255, 204, 1)">数据类型的检测</span></strong></p>
<p>在JavaScript中,要检测一个变量的数据类型,主要有5种方法。</p>
<p><span style="background-color: rgba(204, 255, 204, 1)">1.【typeof】运算符</span></p>
<p>【typeof】返回一个表示数据类型的字符串,返回结果包括7种:"number"、"boolean"、"string"、"symbol"、"object"、"undefined"、"function"。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">typeof</span> Symbol(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> symbol 有效</span>
<span style="color: rgba(0, 0, 255, 1)">typeof</span> ''; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> string 有效</span>
<span style="color: rgba(0, 0, 255, 1)">typeof</span> 1; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> number 有效</span>
<span style="color: rgba(0, 0, 255, 1)">typeof</span> <span style="color: rgba(0, 0, 255, 1)">true</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> boolean 有效</span>
<span style="color: rgba(0, 0, 255, 1)">typeof</span> undefined; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> undefined 有效</span>
<span style="color: rgba(0, 0, 255, 1)">typeof</span> <span style="color: rgba(0, 0, 255, 1)">new</span> Function(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> function 有效</span>
<span style="color: rgba(0, 0, 255, 1)">typeof</span> <span style="color: rgba(0, 0, 255, 1)">null</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> object 无效</span>
<span style="color: rgba(0, 0, 255, 1)">typeof</span> []; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> object 无效</span>
<span style="color: rgba(0, 0, 255, 1)">typeof</span> <span style="color: rgba(0, 0, 255, 1)">new</span> Date(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> object 无效</span>
<span style="color: rgba(0, 0, 255, 1)">typeof</span> <span style="color: rgba(0, 0, 255, 1)">new</span> RegExp(); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> object 无效</span></pre>
</div>
<p>使用【typeof】运算符时,对于数组和对象,返回的都是"object",没有什么卵用。因此【typeof】主要是用来判断基本数据类型的,当然了,除了Null。那么这时就到【instanceof】运算符上场了。</p>
<p><span style="background-color: rgba(204, 255, 204, 1)">2.【instanceof】运算符</span></p>
<p>【instanceof】运算符是用来判断A是否为B的实例,表达式为:A instanceof B。如果A是B的实例,则返回true,否则返回false。【instanceof】运算符实际上是用来测试一个对象在其原型链中是否存在一个构造函数的prototype属性的。</p>
<div class="cnblogs_code">
<pre>[] <span style="color: rgba(0, 0, 255, 1)">instanceof</span> Array; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true</span>
{} <span style="color: rgba(0, 0, 255, 1)">instanceof</span> Object; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true</span>
<span style="color: rgba(0, 0, 255, 1)">new</span> Date() <span style="color: rgba(0, 0, 255, 1)">instanceof</span> Date; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true</span>
<span style="color: rgba(0, 0, 255, 1)">new</span> RegExp() <span style="color: rgba(0, 0, 255, 1)">instanceof</span> RegExp; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true</span></pre>
</div>
<p>但是对于基本数据类型来说,字面量方式创造出来的结果和实例方法创建是有一定的区别的。</p>
<div class="cnblogs_code">
<pre>console.log(1 <span style="color: rgba(0, 0, 255, 1)">instanceof</span> Number); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> false</span>
console.log(<span style="color: rgba(0, 0, 255, 1)">new</span> Number(1) <span style="color: rgba(0, 0, 255, 1)">instanceof</span> Number); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true</span></pre>
</div>
<p>从严格意义上来讲,只有实例创建出来的对象才是标准的对象数据类型值,也是标准的Number这个类的一个实例;对于字面量创建出来的结果是基本的数据类型值,不是严谨的实例,但是由于JavaScript的松散特点,导致了可以使用Number.prototype上提供的方法。只要在当前实例的原型链上,我们用其检测出来的结果都是true。在类的原型继承中,我们最后检测出来的结果未必是准确的(坑爹)。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> arr = ;
</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> fn(){}

console.log(arr </span><span style="color: rgba(0, 0, 255, 1)">instanceof</span> Array); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true</span>
console.log(arr <span style="color: rgba(0, 0, 255, 1)">instanceof</span> Object);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true</span>
console.log(fn <span style="color: rgba(0, 0, 255, 1)">instanceof</span> Function); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true</span>
console.log(fn <span style="color: rgba(0, 0, 255, 1)">instanceof</span> Object); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true</span></pre>
</div>
<p>另外,【instanceof】运算符也不能用来检测null和undefined。对于这两种特殊的数据类型,对应的类是Null和Undefined,浏览器把这两个类保护起来了,不允许访问使用。</p>
<p><img src="https://img2018.cnblogs.com/blog/842514/201905/842514-20190504003823446-964659193.png" alt=""></p>
<p>而对于数组的类型判断,其实还可以用ES6新增的Array.isArray()。</p>
<div class="cnblogs_code">
<pre>Array.isArray([]);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true</span></pre>
</div>
<p><span style="background-color: rgba(204, 255, 204, 1)">3.【===】严格运算符</span></p>
<p>【===】运算符只能用于判断null和undefined,因为这两种类型的值都是唯一的。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> a = <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)"> b;

console.log(</span><span style="color: rgba(0, 0, 255, 1)">typeof</span> a); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> "object"</span>
console.log(<span style="color: rgba(0, 0, 255, 1)">typeof</span> b); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> "undefined"</span>
console.log(a === <span style="color: rgba(0, 0, 255, 1)">null</span>); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true</span>
console.log(b === undefined); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true</span></pre>
</div>
<p><span style="background-color: rgba(204, 255, 204, 1)">4.【constructor】属性</span></p>
<p>【constructor】的作用与【instanceof】非常相似,但是【constructor】检测Object与【instanceof】不一样,还可以处理基本数据类型的检测。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> arr = ;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> reg = /^$/; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 正则表达式</span>
<span style="color: rgba(0, 0, 0, 1)">
console.log(arr.constructor </span>=== Array); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true</span>
console.log(arr.constructor === RegExp); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> false</span>
console.log((1).constructor === Number); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true</span>
console.log(reg.constructor === RegExp); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true</span>
console.log(reg.constructor === Object); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> false</span></pre>
</div>
<p>因为null和undefined是无效的对象,因此是不会有constructor存在的,这两种类型的数据需要通过其它方式判断,比如上面的【===】严格运算符。</p>
<p>另外,函数的constructor是不稳定的。这个主要体现在把类的原型进行重写,在重写的过程中很有可能出现把之前的constructor给覆盖了的情况,这样检测出来的结果就是不准确的。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> Fn(){}
Fn.prototype </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Array();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> f = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Fn;
<br>console.log(f.constructor); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Array</span></pre>
</div>
<p><span style="background-color: rgba(204, 255, 204, 1)">5.【Object.prototype.toString.call()】函数</span></p>
<p>【Object.prototype.toString.call()】是<span style="background-color: rgba(204, 255, 204, 1)">最准确、最常用</span>的方式。首先获取Object原型上的toString()方法,让方法执行,然后让toString()方法中的this指向第一个参数的值。为什么要这样写而不是用对象直接调用toString()方法,是因为每个类重写了toString()方法,而实际要调用的是Object的原型方法toString(),不理解的话建议去看看原型链继承相关的知识。</p>
<p><strong><img src="https://img2018.cnblogs.com/blog/842514/201905/842514-20190504103141413-788813953.png" alt=""></strong></p>
<p>Object上的toString的作用是返回当前方法执行的主体(方法中的this)所属类的详细信息,即"",其中第一个object代表当前实例是对象数据类型的(固定值,只有这一个候选值),第二个Object代表的是this所属的类是Object,候选值有String、Number、Date等。</p>
<div class="cnblogs_code">
<pre>Object.prototype.toString.call(''); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> </span>
Object.prototype.toString.call(1); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> </span>
Object.prototype.toString.call(<span style="color: rgba(0, 0, 255, 1)">true</span>); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> </span>
Object.prototype.toString.call(undefined); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> </span>
Object.prototype.toString.call(<span style="color: rgba(0, 0, 255, 1)">null</span>); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> </span>
Object.prototype.toString.call(<span style="color: rgba(0, 0, 255, 1)">new</span> Function()); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> </span>
Object.prototype.toString.call(<span style="color: rgba(0, 0, 255, 1)">new</span> Date()); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> </span>
Object.prototype.toString.call([]); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> </span>
Object.prototype.toString.call(<span style="color: rgba(0, 0, 255, 1)">new</span> RegExp()); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> </span>
Object.prototype.toString.call(<span style="color: rgba(0, 0, 255, 1)">new</span> Error()); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> </span>
Object.prototype.toString.call(document); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> </span>
Object.prototype.toString.call(window); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> window是全局对象global的引用</span></pre>
</div>
<p>关于toString的重要补充:toString的本意是转换为字符串,一般用来将<span style="background-color: rgba(204, 255, 204, 1)">值</span>转换为字符串。但是对于Number、String、Boolean、Array、RegExp、Date、Function原型上的toString属性(值是函数),都是用于把当前的<span style="background-color: rgba(204, 255, 204, 1)">数据类型</span>转换为字符串,Object上的toString也是同样的,返回的是数据类型的字符串,而不是值的字符串。</p>
<p>&nbsp;</p>
<p>"这世上没有平白无故的闪闪发光。"</p>

</div>
<div id="MySignature" role="contentinfo">
    你要去做一个大人,不要回头,不要难过。<br><br>
来源:https://www.cnblogs.com/yanggb/p/10807260.html
頁: [1]
查看完整版本: javascript的数据类型检测