/************************ 原型 ************************/
// 每个函数都有一个特殊的属性叫作原型(prototype), 默认为空函数,可以重写
function fn1() {}
console.log(fn1.prototype)
// 重写原型之后会导致 constructor 指向错误
fn1.prototype = {}
console.log(fn1.prototype)
// 需将 constructor 重新指向当前构造函数
fn1.prototype.constructor = fn1
/************************ 原型对象 ************************/
// 每一个函数的原型对象指向 Function 的原型
function fn() {}
console.log(fn.__proto__ === Function.prototype) // true
// 每一个数组的原型对象指向 Array 的原型
const arr = []
console.log(arr.__proto__ === Array.prototype) // true
// 每一个对象(除 new 出来的)的原型对象指向 Object 的原型
const obj = {}
console.log(obj.__proto__ === Object.prototype) // true
console.log(Function.prototype.__proto__ === Object.prototype) // true
console.log(Array.prototype.__proto__ === Object.prototype) // true
/************************ 继承 ************************/
// 通过对象冒充(call/apply)的方式实现继承
function Person(name, age, sex) {
this.name = name
this.age = age
this.sex = sex
this.des = 'Person class'
}
Person.prototype.myself = function() {
console.log('my name is' + this.name)
}
function Status(name, age, sex, student) {
Person.call(this, name, age, sex)
this.student = student
}
Status.prototype.duties = function() {
console.log('我的职责是:好好学习,天天向上!')
}
function Teacher(name, age, sex, subject) {
Person.call(this, name, age, sex)
this.subject = subject
}
Teacher.prototype.duties = function() {
console.log('我的职责是:认真上好每一堂课!')
}
const s1 = new Status('Tom', 20, '男', '20041002')
console.log(s1)
s1.duties()
// s1.myself()
// 通过对象冒充(call/apply)的方式继承时,只能继承构造函数里面的属性及方法,不能继承原型上面的
// 对象冒充(call/apply) + 实例化构造函数的模式实现继承
function Person(name, age, sex) {
this.name = name
this.age = age
this.sex = sex
this.des = 'Person class'
}
Person.prototype.myself = function() {
console.log('my name is' + this.name)
}
function Status(name, age, sex, student) {
Person.call(this, name, age, sex)
this.student = student
}
Status.prototype = new Person()
Status.prototype.constructor = Status
Status.prototype.duties = function() {
console.log('我的职责是:好好学习,天天向上!')
}
const s2 = new Status('Tom', 20, '男', '20041002')
console.log(s2)
s2.duties()
s2.myself()
// 多实例化了一次构造函数
// 对象冒充(call/apply) + Object.create()
function Person(name, age, sex) {
this.name = name
this.age = age
this.sex = sex
}
Person.prototype.myself = function() {
console.log('my name is' + this.name)
}
function Status(name, age, sex, student) {
Person.call(this, name, age, sex)
this.student = student
}
Status.prototype = Object.create(Person.prototype)
Status.prototype.constructor = Status
Status.prototype.duties = function() {
console.log('我的职责是:好好学习,天天向上!')
}
const s3 = new Status('Tom', 20, '男', '20041002')
console.log(s3)
s3.duties()
s3.myself()
// 在上面的方案里面少了一次构造函数的实例化
/************************ 原型链 ************************/
function Person(name, age, sex) {
this.name = name
this.age = age
this.sex = sex
}
Person.prototype.des = 'Person class'
Person.prototype.myself = function() {
console.log('my name is' + this.name)
}
function Status(name, age, sex, student) {
Person.call(this, name, age, sex)
this.student = student
}
Status.prototype = Object.create(Person.prototype)
Status.prototype.constructor = Status
Status.prototype.duties = function() {
console.log('我的职责是:好好学习,天天向上!')
}
const s4 = new Status('Tom', 20, '男', '20041002')
console.log(s4.des)
console.log(s4.type)
// s4.des/s4.type 首先从 s4 实例上开始查找,找不到再从原型对象中找
// Status.prototype 中也找不到接着再从原型对象中找
// Person.prototype 中找得到 des 返回结果,找不到 type 接着往原型对象中找
// null 到达原型链顶层,最后对找不到的属性返回 undefined
console