1. __proto__
和 prototype
, Object.create()
、Object.getPrototypeOf()
和 Object.setPrototypeOf()
1.1 __proto__
__proto__
是每个对象都有的一个属性,可称为隐式原型。一个对象的隐式原型指向构造该对象的构造函数的原型,即指向构造函数的prototype
。示例:
let a = {
name: "luojian"
}
对象 a 的图示:
1.2 prototype
prototype
是函数(除部分内置函数)外特有的属性,称为原型属性。这个属性是一个指针,指向一个对象,称为原型对象。原型对象包含所有实例共享的属性和方法。原型对象有一个constructor
属性,指向原构造函数。示例:
function A(id) {
this.id = id
}
A.prototype.getID = function() {
return this.id
}
构造函数 A 的图示:
1.3 Object.create()
、Object.getPrototypeOf()
和 Object.setPrototypeOf()
Object.create(p)
创建一个以p为原型的对象,即对象的__proto__
属性为 p。Object.getPrototypeOf()
和Object.setPrototypeOf()
用于获取和设置对象的原型(__proto__
属性)
let p = {
name: "a"
}
let a = {}
let b = new Object()
let c = Object.create(null)
let d = Object.create(p)
console.log(a.__proto__) // Object
console.log(b.__proto__) // Object
console.log(c.__proto__) // undefined
console.log(d.__proto__) // p
console.log(Object.getPrototypeOf(d)) // p
// 将 d 的原型设置为 a
Object.setPrototypeOf(d, a)
console.log(Object.getPrototypeOf(d)) // a
2. javascript 继承
封装一个对象由构造函数与原型共同组成,因此继承也会分别有构造函数的继承和原型的继承。
先封装一个父类对象 Person
:
let Person = function(name, age) {
this.name = name
this.age = age
}
Person.prototype.getName = function() {
return this.name
}
Person.prototype.getAge = function() {
return this.age
}
Student
继承 Person
let Student = function(name, age, grade) {
// 构造函数继承
Person.call(this, name, age)
this.grade = grade
}
Student.prototype = Object.create(Person.prototype, {
// 重新指定新的constructor属性
constructor: {
value: Student
},
// 添加新的实例共享属性或方法
getGrade: {
value: function() {
return this.grade
}
}
})