咱们在学习javascript时,常常会听到“万物皆对象”,可是呢,其实万物皆对象的对象也有区别。分为普通对象和函数对象。
1.对象分为函数对象和普通对象
经过new Function()建立的对象都是函数对象,其余的都是普通对象。javascript
2.构造函数
而提到new关键字,咱们不得不提到构造函数。构造函数又分为自定义构造函数及native构造函数(即构造器)
2.1 自定义构造函数java
function Person(name,age,job){ this.name = name; this.age = age; this.job = job; } var miya = new Person('miya',18,'engineer'); //miya是构造函数Person的实例;
而实例的构造函数属性(constructor) 都指向构造函数
即:miya.constuctor = Person
2.2 构造器
js内置的构造器包括Number,Boolean,String,Object,Function,Array,RegExp,Error,Date等
一样的,咱们的构造器的实例也有一个constuctor指向它的构造器
函数
let miya= new Array() miya.constuctor ==Array;
经过以上的分析,咱们能够获得如下这张图
这里扩展一下,其实咱们在作类型判断的时候习惯用typeof,typeof判断简单数据类型的时候实际上是ok的。可是typeof有判断复杂数据类型不是很清晰,获得的基本是String或者Function
好比一下图示判断
可是,经过上述咱们知道构造器的实例都有一个constructor的属性指向构造器。那其实咱们直接用constructor即可以清晰地知道这个实例从哪里来。
3.原型对象
每一个函数对象都有一个prototype属性,这个属性指向函数的原型对象即prototype。
全部的prototype会有一个默认的constuctor属性,指向函数对象自己。 学习
function Person(name,age,job){ this.name = name; this.age = age; this.job = job; } Person.prototype.sayName = function () { console.log(this.name); }; let miya = new Person('miya',18,'engineer'); let tiffany = new Person('tiffany',18,'engineer'); miya.sayName(); //miya tiffany.sayName(); //tiffany console.log(miya.sayName == tiffany.sayName); //true console.log(Person.prototype.constructor == Person); //true
经过:Person.prototype.constuctor = Person ,由于构造函数的实例是有一个constructor的属性指向构造函数的,咱们能够获得结论其实Person.prototype也是Person的实例
即:原型对象是构造函数的一个实例【原型对象(Function.prototype除外)是一个普通对象,而不是函数对象】this
4.__proto__属性
4.1 JS在建立对象的时候都会有一个__proto__指向它的构造函数的原型对象
其实,每一个对象都有一个__proto__属性,但只有函数对象有prototype属性。
所以,能够获得如下这样图。
4.2构造函数扩展
而咱们的构造函数本质上都是从Function new出来的。他们本质上都是Function的一个实例。都有一个__proto属性指向Function的原型,也有一个constructor属性指向Function。
提示:Math,JSON是以对象形式存在的,无需new。他们的__proto__是Object.prototype spa
所以能够获得如下的图示,全部的函数对象的__proto__都指向Function.prototype(是一个空函数)
5.函数对象
1.全部的构造器都是经过Function new出来的,他们都是Function的实例,他们的__pro__都指向Function.prototype,甚至包括根构造器Object及Function自己。prototype
Number.__proto__ === Function.prototype // true Number.constructor == Function //true String.__proto__ === Function.prototype // true String.constructor == Function //true Object.__proto__ === Function.prototype // true Object.constructor == Function // true Function.__proto__ === Function.prototype // true Function.constructor == Function //true
2.除Object.prototype外,全部的构造器的prototype的__proto__属性都指向Object.prototype3d
Function.prototype.__proto__ === Object.prototype; // true Number.prototype.__proto__ === Object.prototype; // true String.prototype.__proto__ === Object.prototype; // true Array.prototype.__proto__ === Object.prototype; // true Boolean.prototype.__proto__ === Object.prototype; // true Object.prototype.__proto__ === Object.prototype; // true
3.那Object.prototype的__proto__属性是指向null的。code
Object.prototype.__proto__ === null; // true
Function.prototype也是惟一一个typeof XXX.prototype为 function的prototype
推导Function.prototype.__proto__是什么呢? Object.prototype
全部的构造器都继承Function.prototype的属性及方法 =>全部的构造器函数都是普通的js函数能够用Object的方法
Object.prototype.__proto__ == null
对象
console.log(typeof Function.prototype) // function console.log(typeof Object.prototype) // object console.log(typeof Number.prototype) // object console.log(typeof Boolean.prototype) // object console.log(typeof String.prototype) // object console.log(typeof Array.prototype) // object console.log(typeof RegExp.prototype) // object console.log(typeof Error.prototype) // object console.log(typeof Date.prototype) // object console.log(typeof Object.prototype) // object
补充:
null是一个独立数据类型,而不是一个空引用,只是指望此处引用一个对象 https://developer.mozilla.org... typeof null == Object是一个遗留bug