1. prototype & _ proto _
-
prototype: 每一个函数在创建的时候,JS会同时为这个函数创建一个对应的prototype对象。因此prototype属性是作为函数独有的属性,含义:函数的 原型对象,即由这个函数创建的所有实例的原型对象(函数上的属性)
-
_ proto _: 当函数经过new调用时,这个函数就成为了构造函数,返回一个全新的实例对象,这个实例对象就会有一个_ proto _属性,指向构造函数的原型对象;该属性在 ES6 时被标准化,但因为性能问题并不推荐使用,推荐使用 Object.getPrototypeOf()(对象上的属性)
-
实例对象. _ proto _ === 构造函数. prototype
2.constructor
constructor: 该属性也是作为对象才会拥有,从一个对象指向一个函数,含义:指向该对象的构造函数,每个对象都有自己的构造函数(本身拥有或是继承而来)
- 理解:
每个对象都可以找到其对应的constructor,原因是创建对象的前提即有constructor,否则他们如何指向自己的构造函数呢,而这个constructor有可能是对象自身显示定义也有可能是 _ proto _ 在原型链中找到的,单从constructor属性来说,其实是只有prototype对象才拥有,因此通过构造函数创建出来的对象,即使没有constructor属性但它依然能够通过 _ proto _ 找到自己的constructor。
引用类型 constructor 属性值是可以修改的(在接下来说到对象的创建方式上会有所体现),但是对于基本类型来说是只读的,当然 null 和 undefined 没有 constructor 属性。
例:
function Foo(){
...
}
let f1=new Foo()
此时:
f1. __proto__===Foo. prototype
Foo. prototype.constructor===Foo
f1对象本身没有constructor,但通过__proto__找到Foo. prototype,而在Foo. prototype上有自己的constructor,因此此时的f1.constructor就表示从Foo. prototype身上继承而来的constructor,于是指向Foo
3. 原型与原型链
原型:实际上就是构造函数的prototype属性所指的对象,也就是函数在创建的时候js同时为这个函数创建的那个对应的prototype对象,简称原型,而它存在的作用其一就是可以找到公用的属性与方法。
原型链:对象通过__proto__属性指向父类对象,直到指向null为止的一条原型指向链条。
- 📢:函数Function的构造函数就是它自己,因为Function可以看做是一个函数,也可以看做一个对象,而所有函数和对象最终都是由Function这个构造函数得来。
function Parent(age) {
this.age = age;
}
var p = new Parent(50);
p; // Parent {age: 50}
p.__proto__ === Parent.prototype; // true
p.__proto__.__proto__ === Object.prototype; // true
p.__proto__.__proto__.__proto__ === null; // true