es5:
function Person(name,age) {
this.name = name;
this.age = age;
}
Person.sayHi = function () {
console.log(123);
}
// 创建一个实例
const p = new Person('张三',18);
// 在new的过程中发生了什么?
// 可以理解为:
function Person ('张三',18) {
// 创建一个空对象并让this指向这个空对象
const temp = {};
this = temp;
// 原型绑定,将实例的__proto___(隐式原型)指向构造函数的原型对象
this.__proto__ = Person.prototype;
this.name = '张三';
this.age = 18;
// 放回当前实例
return this;
}
// 注意此处,先在构造函数上添加了sayHi 方法,再创建了p实例
p.sayHi() // 报错 p.sayHi is not a function
Person.sayHi.call(p) // 123
p.__proto__.sayHi() // p.__proto__.sayHi is not a function
Person.sayHi() // 123
Person.prototype.sayHi() // Person.prototype.sayHi is not a function
上述操作证明:
在构造函数 Person 上单独添加的方法是静态方法,
使用Person构造函数创建出来的实例身上并无该方法,且该静态方法也不在其原型对象上 !!!
Person.prototype.sayHi = function () {
console.log(123);
}
p.sayHi() // 123
p.__proto__.sayHi() // 123
Person.prototype.sayHi() // 123
Person.sayHi() // Person.sayHi is not a function
上述操作证明:
在构造函数的原型对象prototype上添加的方法,
在其构造的实例中可以直接使用,但是构造函数本身并未添加该方法,因此:
Person.sayHi() // Person.sayHi is not a function
综上所述: 在构造函数创建完成后,其后所有创建的实例身上只有一开始构造函数中所拥有的属性及方法,后面单独向构造函数添加
的方法和属性均为静态属性和方法,实例上均无法访问和拥有,除非在构造函数的原型上添加!!!
因此可以得出以下关系:
Person.prototype === p.__proto__ // true;
p.constructor === Person // true
es6:
class Person{
constructor(name,age) {
this.name = name;
this.age = age
}
sayHi(){
console.log(123)
}
}
const p = new Person('张三',18);
console.log(p.sayHi()) // 123
console.log(p.__proto__.sayHi()) // 123
console.log(Person.prototype.sayHi()) // 123
console.log(Person.sayHi()) // Person.sayHi is not a function
上述操作证明:
在es6类中声明的方法(sayHi),是挂载在构造函数的原型对象上的
-------------------------------------------------------------------------------------------------
class Person{
constructor(name,age) {
this.name = name;
this.age = age
}
static sayHi(){
console.log(123)
}
}
const p = new Person('张三',18);
console.log(p.sayHi()) // p.sayHi is not a function
console.log(p.__proto__.sayHi()) // p.__proto__.sayHi is not a function
console.log(Person.prototype.sayHi()) // Person.prototype.sayHi is not a function
console.log(Person.sayHi()) // 123
上述操作证明:
在es6类中声明的方法(sayHi),方法前面加上了static后,该方法是挂载在构造函数Person上的,
通过构造函数创建的实例身上并未拥有该方法,
且构造函数的原型对象和实例的隐式原型上也均为拥有该方法
es6的继承:extends
class Person{
constructor(name,age) {
this.name = name;
this.age = age
}
sayHi(){
console.log(123)
}
}
class Cp extends Person {
constructor(name,age,city) {
super(name,age);
this.city = city;
}
}
super关键字的作用:在继承父级class时使用,当父类构造函数发生改变时,子类无需维护,可主动继承父类的改变
如上 (this.name = name; this.age = age),当父类构造函数中变成如下代码时
(this.name = 'name:' + name; this.age = 'age :' + age),子类Cp中无需手动更改,则会主动继承这一变动
而传入的city则是子类构造函数中定义city属性时所需的值
es5 / es6构造函数解析
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。