原型与原型链

相关属性

  1. prototype
  2. __proto__
  3. constructor

1.prototype

所有者:所有函数都有此属性
指向:构造函数所创建实例对象的原型对象
可以理解为一个节点,构造器实例化的对象可以在原型对象上继承属性与方法

function Student(name) {
    this.name = name
}
let std1 = new Student("张三")
Student.prototype.getName = function () {
    console.log(this.name);
}
std1.getName()//张三

2.__proto__

所有者:所有对象都有的属性
指向:该对象的原型对象
可以理解为一个指针,指向该对象的原型对象

function Student() {

}
let std1 = new Student()
Student.prototype == std1.__proto__

3.constructor

所有者:原型对象
指向:实例对象的构造函数
此属性实例对象可以继承

function Student() {

}
let std1 = new Student()
std1.__proto__.constructor == Student //true
std1.constructor == Student //true
Student.prototype.constructor == Student //true

4.原型链

由1、2可以知道,实例化对象的__proto__指向构造函数的prototype,原型对象也有__proto__属性,指向一个原型对象
那么可以将由__proto__连接的原型对象看作一个原型链
因此可以获得以下关系图
image.png

  • 原型对象是通过Object构造函数生成的
  • 红色的线就是原型链
//学校的构造函数
function School(name, age) {
    this.name = name
    this.age = age
}
School.prototype.getName = function () {
    console.log(this.name);

}
School.prototype.getAge = function () {
    console.log(this.age);
}
//实例化一个学校
let sch1 = new School("理工", 100)
//学生的构造函数
function Student(name, age) {
    this.name = name
    this.age = age
}
//实例化一个学生
let std1 = new Student("张三", 18)
//改变一个学生的原型指向
std1.__proto__ = sch1
std1.getName() //张三
console.log(std1.hasOwnProperty("getName"));//false
console.log("getName" in std1);//true
  • std1上并没有getName方法,hasOwnProperty返回false
  • 使用in操作符可以看出getName在原型链上,是std1继承来的方法
  • std1.__proto__ -> sch1.__proto__ -> School.prototype

5.Function与Object的特殊性

Fuction自己构造了自己

function Student() {
}
  • 在创建一个函数时相当于下面代码
let Student = new Function()
  • 那么这个函数可以看做一个实例化的对象,也有__proto__属性,Function是构造函数
function Student() {
}
Student.__proto__ === Function.prototype //true
  • Function是一个函数应该也有一个构造函数,并且这个构造函数就是它自身
Function.__proto__ === Function.prototype

Object是由Function构造而来

let obj = {}
let obj = new Object()
  • 字面量形式创建一个对象就相当于用new实例化一个Object
  • Object就是一个构造函数,函数是不是应该是由new实例化的Function,Object是Function的实例化对象,则有__proto__属性
Object.__proto__ === Function.prototype //true
Object.__proto__ === Function.__proto__ //true
  • 由于Function作为构造函数是由自身构造而来,Function的__proto__与prototype相同
  • Object作为构造函数是由Function构造而来,看成一个实例化的对象,那么Object的__proto__指向Function的prototype
  • 最后可以得到Object.__proto__ === Fuction.__proto__
  • 那么其他内置对象是不是也有同样的特性呢?

总结

理解原型与原型链,主要还是分清谁有什么属性,也就是prototype、__proto__、constructor从属于谁,函数?对象?原型?它们分别又代表什么
第5点只是辅助理解,中间也在强调它是什么性会有什么属性

怼怼
73 声望6 粉丝