什么是原型
首先先来看一个例子
class Student {
constructor(name, score) {
this.name = name;
this.score = score;
}
introduce() {
console.log(`我是${this.name},考了${this.score}分`)
}
}
class Teacher {
constructor(name, subject) {
this.name = name;
this.subject = subject;
}
teach() {
console.log(`我是${this.name},我教${this.subject}`)
}
}
const student = new Student('小明', 90);
const teacher = new Teacher('老张', '计算机');
console.log(student);
student.introduce();
console.log(teacher);
teacher.teach();
然后打印出 student
,如下所示,
student
有两个属性 name
和 score
,
然后将它们打印出来,从图片可以看出都有各自的属性和执行了各自的方法,我们发现这两个实例都有一个 name
属性,是不是可以把这个属性通过继承的方式传入呢,我们可以新建一个 Person
类,它传入一个 name
属性,还给它添加了一个 eat
的方法,然后改写 Student
类和 Teacher
类,如下:
class Person {
constructor(name) {
this.name = name;
}
eat() {
console.log('吃鸡')
}
}
class Student extends Person {
constructor(name, score) {
super(name);
this.score = score;
}
...
}
class Teacher extends Person {
constructor(name, subject) {
super(name);
this.subject = subject;
}
...
}
图片
可以看到能正常显示,并且它们的 __proto__
上都有对应的方法,这个 __proto__
就叫做隐式原型,虽然我们实例化的时候并没有传入 introduce
方法或者 teach
方法,但是可以通过 student.introduce()
和 teacher.teach()
直接调用,而 Student.prototype
则称为显式原型,它们指向的其实都是同一个对象,因此 student.__proto__ === Student.prototype
的结果是 true
的,
用图表示如下:
图片原型链
同样是上面的例子,调用 student.eat()
的话会打印‘吃鸡’,可以发现它的方法是在 student.__proto__.__proto__
上,它本身没有这个方法,所以会去原型上去找,发现还是找不到,所以再去原型的原型上去找,结果找到了,这种逐级向上查找构成一个链式调用,这就是原型链。
每个对象都有一个原型(__proto__
),称为隐式原型,指向构建这个实例的类的(prototype
)显式原型,如果在一个对象上尝试查找某个属性或方法,当找不到的话,就会去它的隐式原型上去查找,直到查找成功或者为 null
,用图表示如下:
如果想知道一个对象的属性或方法是否是它本身的可以用 hasOwnProperty()
,它是在Object.prototype里的方法,可以看到 Object.prototype
它的原型是 null
,说明它是最顶层了。
instanceof判断类型
instanceof
可以用来判断一个数据的类型,通常用 typeof
的话只能判断基本数据类型,对于引用类型可以通过 instanceof
来进行判断,它是根据被判断对象在原型或原型链上是否存在,如果存在的话就会返回true
,比如
teacher instanceof Array // ==> false
teacher instanceof Object // ==> true
teacher instanceof Person // ==> true
teacher instanceof Teacher // ==> true
网友评论