一篇彻底理解JS中的prototype、__proto__与constructor

1.基本类型不是对象(boolean、undefined、number、string)
2.引用类型都是对象(Array,function ,Object)
3.对象是通过函数创建,并且强调,对象字面量也是通过函数创建,举例说明,ES6继承的语法糖
4.函数有的是显式原型prototype  
5.对象有的是隐式原型__proto__     和构造器 constructor
6.但是由于JS中函数也是一种对象,所以函数也拥有__proto__和constructor
7.__proto__ 属性,它是对象所独有的,可以看到__proto__属性都是由一个对象指向一个对象.
它的作用就是当访问一个对象的属性时,如果该对象内部不存在这个属性,那么就会去它的__proto__属性所指向的那个对象(可以理解为父对象)里找,如果父对象也不存在这个属性,则继续往父对象的__proto__属性所指向的那个对象(可以理解为爷爷对象)里找,如果还没找到,则继续往上找…直到原型链顶端null(可以理解为原始人。。。),再往上找就相当于在null上取值,会报错(可以理解为,再往上就已经不是“人”的范畴了,找不到了,到此结束。
8.prototype属性,它是函数所独有的,它是从一个函数指向一个对象。它的含义是函数的原型对象,也就是这个函数(其实所有函数都可以作为构造函数)所创建的实例的原型对象,它的作用就是包含可以由特定类型的所有实例共享的属性和方法,也就是让该函数所实例化的对象们都可以找到公用的属性和方法。任何函数在创建的时候,其实会默认同时创建该函数的prototype对象。
8.constructor属性也是对象才拥有的,它是从一个对象指向一个函数,含义就是指向该对象的构造函数,每个对象都有构造函数(本身拥有或继承而来,继承而来的要结合__proto__属性查看会更清楚点
举栗:
  class Person {
    constructor(name) {
      this.name = name;
    }
  }
  var xiaoming = new Person('张三');
  console.log(xiaoming);

输出结果:
Person {name: "张三"}
   name: "张三"
   __proto__: Object

__proto__就是由xiaoming(实例对象)指向Person 对象。

举栗:
console.log(xiaoming.__proto__);

输出结果:
{constructor: ƒ}
   constructor: ƒ Person(name)
   arguments: (...)
   caller: (...)
   length: 1
   name: "Person"
   prototype: {constructor: ƒ}
    __proto__: ƒ ()
    [[FunctionLocation]]: index.vue?0dbc:133
     [[Scopes]]: Scopes[3]
     __proto__: Object
  里面的构造器指向的是Person里面的构造函数,因为是函数,所以有prototype(显式原型)

举栗:
  console.log(xiaoming.__proto__.__proto__);


输出的是:
{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
 constructor: ƒ Object()
  hasOwnProperty: ƒ hasOwnProperty()
  isPrototypeOf: ƒ isPrototypeOf()
  propertyIsEnumerable: ƒ propertyIsEnumerable()
  toLocaleString: ƒ toLocaleString()
  toString: ƒ toString()
  valueOf: ƒ valueOf()
  __defineGetter__: ƒ __defineGetter__()
  __defineSetter__: ƒ __defineSetter__()
  __lookupGetter__: ƒ __lookupGetter__()
  __lookupSetter__: ƒ __lookupSetter__()
  get __proto__: ƒ __proto__()
  set __proto__: ƒ __proto__()
 寻找构造函数的原型,因为函数也是一个引用类型,所以构造函数指向Object对象

举栗:
  console.log(xiaoming.__proto__.__proto__.__proto__);

已无隐式原型,内存地址指向空对象指针,输出null

猜你喜欢

转载自www.cnblogs.com/codedisco/p/12543584.html