构造函数
function MakePerson(name) {
// this 是 实例对象 也就是 实例添加了 name sing 属性 与方法 value 由实例化时 决定
this.name = name
// 多个实例 多个指向 开辟多个内存空间 函数是复杂数据类型 多个 占用内存
this.sing = function () {}
}
const person = new MakePerson('aa')
const name = person.name // 通过 构造函数中 this 实例 有了该属性
// 静态 属性 方法 -- 在构造函数本身上添加
// 只能通过构造函数本省调用 MakePerson.sex; person不可
MakePerson.sex = '男'
原型对象 prototype
// 原型对象 -- prototype
// 构造函数 -- prototype 所有实例共享
MakePerson.prototype.sing2 = function () {}
person.sing2()
// 实例对象 person身上系统自动添加了__proto__指向构造函数原型对象
person.__proto__ === MakePerson.prototype
// 指回构造函数
MakePerson.prototype.constructor = MakePerson
// 原型链
person.__proto__ === MakePerson.prototype
MakePerson.prototype.__proto__ === Object.prototype
Object.prototype.__proto__ === null //到顶了
语法糖 class
class MakePerson2 {
// 必须有 constructor 方法,如果没有显式定义,一个默认的 constructor 方法会被默认添加
// new 命令创建对象实例时,自动调用该方法
constructor(name) {
this.name = name // this 指 实例对象
}
sing() {} // MakePerson2.prototype.sing = function () {} 实例调用 共享
static sex = '男'
}
const p = new MakePerson2('name')
p.name
p.sing()
继承 1借用 构造函数 继承属性 2原型对象 继承方法 组合继承
function Father(name) {
this.name = name
}
Father.prototype.work = function () {}
function Son(name) {
/**
* Son实例 继承 Father name 属性
* this指向 子构造函数对象实例
* 相当于父亲里面 son.name = name;
*/
Father.call(this, name)
}
// Son.prototype = Father.prototype; 有问题修改子原型对象,父原型对象一起变化,地址相同
Son.prototype = new Father()
// 利用对象的形式修改了原型对象,需要重新指回原来的构造函数
Son.prototype.constructor = Son
// son.__proto__ === Son.prototype === new Father.__proto__ === Father.prototype;
// 等价于上面 两行
Son.prototype = Object.create(Father.prototype)
// 语法糖 class extends super
class Father2 {
constructor(name,sex) {
this.name = name
this.sex= sex
}
work() {
console.log(this) // super 调用 this 指向 子类实例
}
}
// 继承父类的属性和方法 可以理解为 super代替了 call extends 代替了 prototype
class Son extends Father2 {
constructor(name, sex,age) {
super(name,sex)
this.age = age
// super.sex sex 为 父类 this.sex 是实例拥有 无法通过super--Father.prototype 访问父类 实例属性与方法
}
}
/**
* super 必须在 constructor 中 必须有
* 必须在 this 之前
* super 作为函数 代表父类构造方法 但是this指向子类实例
* super 作为对象 父类原型对象 Father.prototype
* super调用父类方法时 方法内部 this 指向 子类实例
* super在静态方法中指向父类 而不是父类原型对象
* super在静态方法调用父类方法时 方法内部 this 指向 当前子类 而不是子类实例
*/