让我们红尘作伴,活的潇潇洒洒~~~~~~~~~~~~
首先我们先了解js的数据类型,包含了五大基本数据类型和引用类型,至于es6新出的symbol后续了解。
五大基本数据类型(值类型):number, boolean string, undefined, null
复杂类型(引用类型):Object(包含对象实例,array, function)
为什么有这种区分呢?
1.值类型占用空间固定,值类型的变量会保存在栈内存中,新建和复制变量都只是在栈中新开辟的一块内存。
2.引用类型的变量名会保存在栈内存中,但是变量值会存储在堆内存中,引用类型的变量不会自动销毁,当没有引用变量引用它时,系统的垃圾回收机制会回收它。
举个直观的列子
值类型:
var a = 10;
var b = a;
b= 11;
console.log(a) // 10
上面,b获取的是a值得一份拷贝,虽然,两个变量的值相等,但是两个变量保存了两个不同的基本数据类型值。所以改变b,不影响a
引用类型:
var obj1 = new Object();
var obj2 = obj1;
obj2.name = "引用类型";
console.log(obj1.name); // 引用类型
实际上这个堆内存对象在栈内存的引用地址(obj1)复制了一份给了obj2,obj2仍是指向obj1存在堆内存中的变量值,改变obj2 会影响到堆内存中的变量值,那么obj1引用地址对应的值就会改变
3.值类型上不能添加属性和方法,引用类型可以添加属性和方法
var a = 10;
a.name="值类型";
a.setName=function() {
console.log(a.name)
}
console.log(a.name) // undefined
console.log(a.setName) // undefined
var b = new Object()
b.name="引用类型"
b.setName =function() {
console.log(b.name)
}
console.log(b.name) // 引用类型
console.log(b.setName()) // 引用类型
4.注意值类型和引用类型的比较, 值类型的比较是值的比较(后续会讲隐式转换和强制转换),引用类型的是引用地址的比较
var a = 10;
var b = 10;
console.log(a===b) // true
....
var a = {};
var b = {};
console.log(a===b) //false
好,现在我们大概了解了它们的区别,那有没有可以判断它们究竟谁什么类型呢,不要急,往下看,我查到了一些方法可以供大家参考
1)我们可以使用typeof来检测变量的类型
typeof 123 // number
typeof true //boolean
typeof 'abc' //string
typeof undefined //undefined
typeof null //注意这里判定的类型是object,因为null类型被当做一个空对象引用 typeof {} //object
typeof [] //object
typeof function() {console.log()} //function是可以被typeof检测出来的
但是想要再细节一点区分,还有别的吗,当然
2)instanceof 是用来判断 A 是否为 B 的实例,表达式为:A instanceof B,如果 A 是 B 的实例,则返回 true,否则返回 false,我们可以利用它来检测数组和对象。来模拟一下原理
function instanceofs(A,B) {
var a = A.__proto__;
var b = B.prototype
if(a === b) {
// A的内部属性 __proto__ 指向 B 的原型对象
return true;
}
return false;
}
instanceofs([],Array) 返回的是true 模拟达到了 [] instanceof Array == true
那么有一个问题产生了,[] instanceof Object;// true 为什么也返回true呢?
从 instanceof 能够判断出 [ ].proto 指向 Array.prototype,而 Array.prototype.proto 又指向了Object.prototype,最终 Object.prototype.proto 指向了null

从原型链可以看出,[] 的 proto 直接指向Array.prototype,间接指向 Object.prototype,所以按照 instanceof 的判断规则,[] 就是Object的实例
感觉前端原型咋那么绕是吧。。。
故我们instanceof 只能用来判断两个对象是否属于实例关系, 而不能判断一个对象实例具体属于哪种类型。
3)初次之外还有哦,Object.prototype.toString.call,constructor,举两个列子,大家就能很明白了,至于里面的原理,大家就可以深入去看看原型链这一块
Object.prototype.toString.call({}) // [object object]
[].constructor==Array // true
null 和 undefined 是无效的对象,因此是不会有 constructor 存在的,这两种类型的数据就不能通过constructor方式来判断。
好吧 ,今天第一节就这样结束了,我们下一期见
