javaScript复习—基本类型、引用类型已经判断数据类型的办法
原始值和引用值类型和区别
在javaScript中,变量可以储存两种值:原始值和引用值。
基本类型:原始值代表原始数据类型的值,比如Number、String、Boolean、Null、Undefined、Symbol
引用类型:引用值指的是复合数据类型的值,比如Object(包括数组)、Function、Date、RegExp。所有引用类型都是Object的实例。
变量的存放
- 基本类型的数据存放在栈内存中,基本值在内存中占有固定大小的空间,在栈内存中按值查找。(这里需要注意的是,虽然字符串长度可变,但是ECMAscript还是将它归为基本类型)
- 引用类型的数据存放在堆内存中,引用值的大小不固定,但是他们的内存地址的固定大小的,因此可以将引用值的内存地址存放在栈内存中。也就是当查询引用类型的变量时,先从栈中读取内存地址,再通过地址找到堆中的值
在计算机的数据结构中,栈比堆的运算速度快,而将数组扩充、对象属性的添加等操作放在堆中,可以保证栈的效率不被影响。
原始值和引用值的传递问题
这部分是面试和笔记常见的考点,敲黑板,都给我记!
原始值的传递:当我们把一个原始变量传递给另一个原始变量时,其实是把栈空间中的内容复制到另一个栈空间中,这时候两个原始值传递互并不影响。
let a = 1; let b = a ; a = 2; console.log(a); // 2 console.log(b); // 1
引用值传递: 其实变量中存放的是指向引用值的指针,所以当我们将一个引用变量传递给另一个引用变量时,其实是将这个指针复制了一份传递给另一个变量。简单来说,这两个变量都指向同一个引用值(假设是对象)。当通过方法修改其中一个变量引用的对象的属性后,通过另一个变量访问这个对象,会发现属性值也随之改变了。
let a = { value: 1 }; let b = a; a.value = 2; console.log(a.value); // 2 console.log(b.value); // 2
如何判断数据类型
typeof
typeof是一元操作符,其右侧跟一个一元表达式,并返回这个表达式的数据类型。返回结果用该类型的字符串(全小写)表示,共7种:number、string、boolean、symbol、object、function、undefined
typeof 1; // number 有效判断
typeof "hello world"; // string 有效判断
typeof true; // boolean 有效判断
typeof Symbol(); // symblo 有效判断
typeof new Function; // function 有效判断
typeof undefined; // undefined 有效判断
typeof null; // object 无效判断
typeof new Object; // object 无效判断
typeof []; // object 无效判断
typeof new Date(); // object 无效判断
typeof new RegExp(); // object 无效判断
这里我要放一个我自己之前混起来的点(但是现在解决啦嘿嘿~)
typeof Object; // function
typeof new Object; // object
检讨: 为什么会混起来!!!忘记了Object是对象的构造函数! 当然new Date和Date也是这样的,其他的也是!要举一反三哦!
总结:
- typeof可以准确判断除null之外的基本类型结果
- 对于null,返回结果是object
- 对于引用类型,除function之外返回object
- 对于function,返回结果为function
instanceof
instanceof用来判断A是否为B的实例(A instanceof B),如果是,则返回true
,如果不是则返回false
。
instanceof实现逻辑如下:
instanceof(A,B) {
if(A.__proto__ === B.prototype) {
return true
}
return false
}
这里就扯到原型链了,instanceof其实是在原型链上寻找构造函数的原型和实例对象的关系,如果实例对象通过__proto__指向构造函数的原型(及Parent.prototype === p.__proto__),则返回true
。
我们来瞅瞅这几个栗子:
1 instanceof Number; // false
"hello world" instanceof String; // false
true instanceof Boolean; // false
null instanceof Object; // false 快看!这个和typeof返回的不一样!!!!
null instanceof Null; // 报错 实际并不存在
undefined instanceof Undefinef; // 报错 实际并不存在
instanceof没办法判断原始值的类型!原因是原始值并没有转换成对象,instanceof是没办法检测到原型的,所以直接返回false
。
不过下面这些都是可以判断的啦,我没有写全!
new Date instanceof Date; // true
new Function instanceof Function; //true
[] instanceof Array; // true
[] instanceof Object; // true
...
大家快看看这个[],其实并不是判断错了哦,只是[].__proto__ === Array.prototype,而且[].__proto__.__proto__ === Object.prototype,所以Instanceof顺着原型链找到这个结果,就返回true
了
然后今天学到了完整的instanceof功能实现:
function myInstanceof(left,right) {
// 首先如果是基本类型及null直接返回false
if(typeof left !== 'object' || left == null) return false;
let proto = Object.getPrototypeOf(left);
while(true) {
// 如果把原型链找到底了都没有找到
if(proto == null) return false;
// 找到了
if(proto == right.prototype) return true;
// 在原型链上找原型的原型
proto = Object.getPrototyprOf(proto);
}
}
constructor
当一个函数被创建的时候,JS引擎就会为它加上prototype原型,而prototype存在一个constructor属性,指向这个函数的引用。
所以constructor判断数据类型的原理其实就是通过寻找构造函数来判断类型
function F() {}
var f = new F();
f.constructor === F; // true
或者
f.__proto__.constructor === F // true
瞅瞅这些热乎乎的栗子呀:
new Date().constructor === Date; // true
new Function().constructor === Function; // true
"hello world ".constructor === String; // true
这里要注意的是访问原型上的内置函数和属性,会导致基本类型到引用类型的转换!所以”hello world”现在已经变成了引用类型了。
Object.prototype.toString.call()
toString()是Object原型上的方法,调用该方法,会返回当前对象的[[Class]]属性,[[Class]]是对象的内部属性,里面包含了对象的类型信息,其格式为[object Xxx],其中Xxx就是对应的具体类型。
对于Object对象,只需要直接调用此方法
var obj = {};
obj.toString(); // [object Object]
而对于其他对象,则需要通过call或者apply来绑定调用的对象
Object.prototype.toString.call('') ; // [object String]
Object.prototype.toString.call(1) ; // [object Number]
但是这个方法其实也有缺陷的!让我们瞅瞅ES6提出的Symbol.toStringTag符号,这个符号是所有对象都具有的属性,它的功能是定义对象[object Xxx]中的Xxx。
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达,可以邮件至 610193653@qq.com,谢谢啦!
文章标题:javaScript复习—基本类型、引用类型已经判断数据类型的办法
本文作者:zzzwyyy
发布时间:2019-11-29, 23:15:46
最后更新:2019-12-16, 12:31:53
原始链接:http://yoursite.com/2019/11/29/javaScript复习——基本类型、引用类型已经判断数据类型的办法/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。