对象分类

  • 普通对象
    • 普通的实例对象:有proto属性(构成原型链),没有prototype属性。
    • 原型对象:(Person.prototype为原型对象,还是constructor属性)原型对象就是构造函数的一个实例对象。person.prototype就是person的一个实例对象。
  • 函数对象
    • 通过new Function()创建的对象,都是函数对象,包括Function、Object、Array、Date、String、自定义函数。这些对象同时拥有proto、prototype属性(指向原型对象)
    • 特例:Function.prototype(是原型对象,又是函数对象)
      1. //函数对象
      2. function F1(){};
      3. var F2 = function(){};
      4. console.log(typeof F1); //function
      5. console.log(typeof F2); //function
      6. console.log(typeof Object); //function
      7. console.log(typeof Array); //function
      8. console.log(typeof Date); //function
      9. console.log(typeof Boolean); //function
      10. console.log(typeof Date); //function
      11. console.log(typeof Function); //function
      12. console.log(typeof Math); //function
      判断以上这些数据类型,要使用instanceof方法。instanceof方法是通过判断原型来判断数据类型
      1. [] instanceof Array;
      2. {} instanceof Object;

Array是函数对象,它是Function的实例对象,Array是通过new Function()创建出来的。Array是Function的实例,所以

  1. Array.__proto__ === Function.prototype // true

原型对象prototype(显式原型)

创建出的每一个函数对象都会有一个prototype显式原型属性,该属性是一个指针,指向一个对象(通过该构造函数, 创建实例对象的原型对象)。

原型对象

  • 原型对象是包括特定类型的,所有实例共享的属性和方法。
  • 特点:可以让所有实例对象共享它的属性和方法

原型对象是普通对象。

Function.prototype该原型对象是个例外,它是原型对象,又是函数对象。但是作为函数对象,它又没有prototype属性

  1. function Person(){};
  2. console.log(typeof Person.prototype) //Object
  3. console.log(typeof Object.prototype) // Object
  4. console.log(typeof Function.prototype) // 特殊 Function
  5. console.log(typeof Function.prototype.prototype) //undefined

本质上,原型对象是构造函数的一个实例对象。Person.prototype是Person函数的实例对象,相当于在Person创建的时候,自动创建了它的实例,并且把这个实例赋值给了prototype。

  1. function Person(){};
  2. var temp = new Person();
  3. Person.prototype = temp;
  4. function Function(){};
  5. var temp = new Function();
  6. Function.prototype = temp; //由new Function()产生的对象都是函数对象

image.png

  1. function Animal(){}
  2. Animal.prototype.name = "宠物"
  3. Animal.prototype.getName = function(){
  4. return this.name
  5. }
  6. let dog = new Animal()
  7. let cat = new Animal()
  8. dog.name = "狗"
  9. console.log(dog.name)
  10. console.log(cat.name)

image.png
解释图中的关系

  1. dog.__proto__ === Animal.prototype
  2. Animal.prototype.__proto__ === Object.prototype
  3. dog.__proto__.__proto__ === Object.prototype
  4. Animal.prototype.constructor === Animal

引入一种经典的原型原型链的图示
495b3953-dcc0-4e79-a35a-07a88d959a25.jpg

原型链proto(隐式原型)

原型链是JavaScript实现继承的主要方法。
原型链基本思路:
利用原型让一个引用类型继承另一个引用类型的属性和方法。
每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针(constructor),而实例对象都包含一个指向原型对象的隐式原型 proto
如果让原型对象等于另一个类型的实例,此时的原型对象将包含一个指向另一个原型的指针

  1. function Animal(){
  2. this.type = "animal";
  3. }
  4. Animal.prototype.getType = function(){
  5. return this.type;
  6. }
  7. function Dog(){
  8. this.name = "dog";
  9. }
  10. Dog.prototype = new Animal();
  11. Dog.prototype.constructor = Dog
  12. Dog.prototype.getName = function(){
  13. return this.name;
  14. }
  15. let wangcai = new Dog();
  1. //原型链关系
  2. wangcai.__proto__ === Dog.prototype
  3. Dog.prototype.__proto__ === Animal.prototype
  4. Animal.prototype.__proto__ === Object.prototype
  5. Object.prototype.__proto__ === null

image.png
image.png