搞懂JS构造函数、原型和原型链

构造函数

构造函数就是函数,任何函数都可以作为构造函数被使用。但是要注意,构造函数有实例成员和静态成员。

function Person(name) {
  // 实例成员,new实例才可以访问
  this.name = name;
}

// 静态成员,构造函数自己才可以访问
Person.age = 18;

let person = new Person('zhangsan');
console.log(person.name); //zhangsan
console.log(person.age); //undefined  实例无法访问静态成员

console.log(Person.name); //Person 不是zhangsan,因为无法直接访问实例成员
console.log(Person.age); //18  构造函数自己可以访问静态成员

原型

Person.prototype 就是原型,它是一个对象,我们也称它为原型对象。 实例对象有一个__proto__属性,指向 Person.prototype

person.__proto__ === Person.prototype; // true

原型对象的 constructor 属性指向构造函数。

Person.prototype.constructor === Person; //true

原型的作用,就是共享方法。 我们通过 Father.prototype.method 可以共享方法,不会开辟空间存储方法。

原型链

原型与原型层层相链接即为原型链。 查找方法时,会从下往上层层查找,原型链的最顶层是 null

Object.prototype.__proto__ === null; //true

总结

按照如下要求实现 Person 和 Student 对象 a)Student 继承 Person b)Person 包含一个实例变量 name, 包含一个实例方法 printName c)Student 包含一个实例变量 score, 包含一个实例方法 printScore d)所有 Person 和 Student 对象之间共享一个方法 common

function Person(name) {
  this.name = name;

  // 定义在构造函数里的方法,每个实例重新构造,彼此不影响
  this.printName = function () {
    console.log(this.name);
  };
}

// 定义在原型对象上的方法,所有实例共享
Person.prototype.common = function () {
  console.log(this.name);
};

function Student(name, score) {
  Person.call(this, name);
  this.score = score;
  this.printScore = function () {
    console.log(this.score);
  };
}

// 子类的原型指向父类的实例,这样就可以顺着原型链共享父类的方法了。并且为子类添加原型方法的时候,不会影响父类。
Student.prototype = new Person();

let person = new Person('张三', 80); //80没有实际用处
let stu = new Student('李四', 100);
console.log(person.printName === stu.printName); //false printName是实例成员,每次new后都会重新构建,不共享
console.log(person.common === stu.common); //true common是原型方法,不同实例都会继承,共享
© 2022  Arvin Xiang
Built with ❤️ by myself