js中有两种对象:object普通对象与function函数对象;
其中,所有的构造函数都是函数对象,例如Number,Object等
使用new构造函数与直接调用出来的数据是有区别的;
var o = new Object(), //构造函数
o1 = Object(); //直接调用
console.log(o == o1);//false,类型相等但是内存不是指向一个地方所以不会相等
console.log(o === o1);//false
var f = new Function(),
f1 = Function();
console.log(f == f1);//false
console.log(f === f1);//false
其中,Obejct/Function/Array由于对象的比较是比较根源的,所以无论是构造函数还是直接调用都是新的内存空间,所以他们生成的对象不会相等。
var n = new Number(),//构造函数,函数对象
n1 = Number();//数值类型
console.log(n == n1);//true,会转换,所以相等。只不过这个对象和数值类型比较的时候被当做数值类型来比较。当使用“===”的时候比较数值相等时再比较数据类型的时候是有别于其他数值类型的。
console.log(n === n1);//false,类型不同,不全等
而基本包装类型Boolean/Number/String使用相等操作符是相等的,因为相等时是用数值类型的规则来比较的,所以会先转换再比较,使用全等是不全等的,这时候因为不转换所以类型就不相等更不要提全等了。
普通对象是没有prototype属性的,只有隐藏属性__proto__。而函数对象两者都有,其中prototype是指向函数对象的原型对象,__proto__属性是创建实例对象的时候对应的函数对象的原型对象。实例对象的__proto__属性就是对应函数对象的原型对象。
1.函数对象的原型对象
原型对象的值实际上是在函数创建时,创建了一个函数的实例对象并赋值给他的prototype。
var temp = new Function();//函数创建
Function.prototype = temp;//赋值,原型对象的值
函数对象的原型对象:
//chrome下的显示效果
Function.prototype;//function() {}
Object.prototype;//Object {}
Number.prototype;//Number {[[PrimitiveValue]]: 0}
Boolean.prototype;//Boolean {[[PrimitiveValue]]: false}
Array.prototype;//[]
String.prototype;//String {length: 0, [[PrimitiveValue]]: ""}
所有函数对象的原型对象都继承原始对象,即fn.prototype.__proto__为原始对象(原始对象在继承属性__proto__)。这其中比较特别的是Object函数,他的原型对象就是原始对象,即Object.prototype。
var f1 = new Function();
var f2 = Function();
var fn3 = function(){}
console.log(f1.prototype.__proto__ === Object.prototype);//true
console.log(f2.prototype.__proto__ === Object.prototype);//true
console.log(f2.prototype.__proto__ === Object.prototype);//true
console.log(Number.prototype.__proto__ === Object.prototype);//true
console.log(Boolean.prototype.__proto__ === Object.prototype);//true
2.继承属性__proto__
__proto__却起到了类似继承的作用。所有的对象起源都是一个空对象,我们把这个空对象叫做原始对象。所有的对象通过__proto__回溯最终都会指向(所谓的指向类似C中的指针,这个原始对象是唯一的,整个内存中只会存在一个原始对象)这个原始对象。
var o = new Object();
o.__proto__;//Object {},原始对象
o.prototype;//undefined
Object.prototype;//Object {}
Object.__proto__;//function(){}
Object.__proto__.__proto__;//Object {}
var f = new Function();
f.__proto__;//function(){}
f.prototype;//Object {}
Function.prototype;//function(){}
Function.__proto__;//function(){}
Function.__proto__.__proto__;//Object {}
原始对象的__proto__属性为null,并且没有原型对象。
//所有的对象都继承自原始对象
//Object比较特殊,他的原型对象也就是原始对象
//所以我们往往用Object.prototype表示原始对象
Object.prototype === o.__proto__;//true Object.prototype === Object.__proto__.__proto__;//true Object.prototype === Function.__proto__.__proto__;//true
//所有的函数对象都继承制原始函数对象,
//Function比较特殊,他的原型对象也就是原始函数对象
Function.prototype === f.__proto__
Function.prototype === Object.__proto__ ;//true
Function.prototype === Function.__proto__;//true
//所以我们往往用Function.prototype表示原始函数对象
//而原始函数对象又继承自原始对象
Function.prototype.__proto__ === Object.prototype;
3.原型链
在使用new方法初始化函数时,得到的新对象的__proto__属性会指向函数对象的原型对象,而函数对象的原型对象又继承至原始对象。
function fn(){};
var test = new fn();