构造函数
构造函数就是函数,任何函数都可以作为构造函数被使用。但是要注意,构造函数有实例成员和静态成员。
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是原型方法,不同实例都会继承,共享