一、继承
function Person(name) {
// 成员变量
this.name = name;
}
// 成员方法
Person.prototype.eat = function () {
console.log("吃饭")
};
// 静态变量
Person.age = 18;
// 静态方法
Person.sleep = function () {
console.log("睡觉")
};
function Student(name, school) {
//继承成员变量
Person.call(this, name);
this.school = school;
}
//继承成员方法(构造函数的prototype重新赋值时需要添加constructor属性)
//Object.create()方法创建一个新对象,使用现有的对象(Person.prototype)来提供新创建的对象({})的__proto__
Student.prototype = Object.create(Person.prototype);
Object.defineProperty(Student.prototype, 'constructor', {
value: Student,
enumerable: false
});
Student.prototype.study = function () {
console.log("学习")
};
//继承静态变量和方法
Student.__proto__ = Person;
Student.level = '7年级';
Student.game = function () {
console.log("游戏")
};
// 测试静态变量和方法的继承
console.dir(Student);
console.log(Student.age);//18
Student.sleep();//睡觉
console.log(Student.level);//7年级
Student.game();//游戏
// 测试成员变量和方法的继承
let stu = new Student('孟美岐', '江南大学');
console.log(stu);
console.log(stu.name);//孟美岐
stu.eat();//吃饭
console.log(stu.school);//江南大学
stu.study()//学习
* 构造函数的属性放在对象上,函数放在原型上;
* 继承属性【Person.apply(this,[name]);】,
继承方法【Student.prototype=Object.create(Person.prototype);】;
* Object.prototype为原型链的最顶层对象;
二、原型
/*
构造函数有一个prototype属性,对象有一个__proto__属性;
对象的__proto__指向构造函数的prototype;
构造函数的prototype有一个constructor属性;
当访问一个对象的属性的时候,首先在这个对象本身进行查找,
如果找到,就直接返回这个属性,且停止查找。
如果没找到,会继续在原型上找,也就是__proto__指向的那个对象。
*/
console.log(student.__proto__==Student.prototype);//true
console.log(student.__proto__.__proto__==Person.prototype);//true
console.log(student.__proto__.__proto__.__proto__==Object.prototype);//true
console.log(student.__proto__.__proto__.__proto__.__proto__);//null
三、原型三角图
【可以让所有对象共享原型对象中的成员】
[null]
↗
↗
Object.prototype ↗
[Object -----------------------------→ [Object
构造函数] ←----------------------------- 原型对象]
↘ Object.prototype.constructor ↗
↘ ↗
↘ ↗
↘ ↗
new Object() p1.__proto__ .__proto__
↘ ↗
↘ ↗
↘ ↗
Person.prototype ↘ ↗
[Person -----------------------------→ [Person
构造函数] ←----------------------------- 原型对象]
↘ Person.prototype.constructor ↗
↘ ↗
↘ ↗
↘ ↗
new Person()实例化 p1.__proto__
↘ ↗
↘ ↗
↘ ↗
↘ ↗
[p1对象]
四、设置原型对象
function Person(pname) {
this.pname = pname
}
//当重新设置构造函数的prototype,一定要重新设置constructor属性
//如果要访问原型对象的成员,必须先设置原型对象,再使用构造函数创建对象
Person.prototype = {
constructor: Person,
setPname: function (pname) {
this.pname = pname
},
getPname: function () {
return this.pname
}
}
//内置对象的prototype为只读属性,不能修改
Array.prototype = {}