1:如何理解原型
javascript规定,每一个函数都有一个prototype对象属性,指向另一个对象(原型链上的)。(指向的是实例对象的__prpto__)
prototype上的所有属性和方法,都会被构造函数的实例继承。
这意味着,我们可以把那些公共的属性和方法,直接定义在prototype上
prototype可以让所有对象实例共享它所包含的属性和方法。也就是说,
不必在构造函数中定义对象信息,而是可以直接将这些信息添加到原型中去。
2:如何理解原型链
实例对象与原型之间的连接,叫做原型链。proto(隐式连接)
js在创建对象的时候,都有一个叫做proto的内置属性,用于指向创建它的函数对象的原型对象prototype
内部原型(proto)和构造器的原型(prototype)
(1)每个对象都有一个proto属性,原型链上的对象正是依靠这个属性连接在一起
(2)作为一个对象,当你访问其中一个的属性或者方法的时候,如果这个对象中没有这个方法或者属性,那么js引擎会访问这个对象的proto属性所指的上一个对象,并在那个对象中查找指定的方法或属性,如果找不到,那就会继续通过那个对象的proto属性 指向的对象进行向上查找,直到这个链表结束
(3)由于__proto__是任何对象都有的属性,而js里万物皆对象,所以会形成一条__proto__连起来的链条,递归访问__proto__必须最终到头,并且值是null
当js引擎查找对象的属性时,先查找对象本身是否存在该属性,如果不存在,会在原型链上查找,但不会查找自身的prototype
原型链的顶层就是Objec.prototype
3:如何理解constructor/instanceof/proto/prototype
function Person(name){
this.name = name
}
var person = new Person('tom')
// 沿着对象的person的__proto__属性 --> 到原型链终端
__proto__:隐式属性,对象的属性,指向这个对象构造函数的原型
constructor:查看实例对象的构造函数
instanceof:
A instanceof B
//判断A对象是不是B构造函数构造出来的
//实质是看A对象的原型链上有没有B的原型
hasOwnProperty:判断属性是否是继承过来的
for(var prop in obj) {
if(obj.hasOwnPrototype(prop)){
console.log(obj[prop])
}
}
3: 什么是继承
一个类获取另一个或者多个类的属性或者方法。
继承可以使得子类具有父类的各种方法和属性,以免重复输出很多代码
4:实现继承的原理
复制父类的方法和属性来重写子类的原型对象
5:怎么实现继承
-
1:原型链继承
-
2:借用构造函数call/apply
-
3:圣杯模式
-
4:class-es6语法
1:原型链继承
Person.prototype.text = 'hehe'
function Person(name,age){
this.name = name;
this.age = age
}
function CopyPerson(){
}
CopyPerson.prototype = Person.prototype
var person = new CopyPerson();
var inhert_person = new Person();
CopyPerson.prototype = inhert_person
2:借用构造函数call/apply(改变this指向)
function Person(name,age){
this.name = name;
this.age = age
}
function CopyPerson(name,age,sex){
Person.call(this,11)
}
var person = new CopyPerson(11,22,33)
3:圣杯模式
function inheritFunc(origin,target){
function func(){
}
func.prototype = origin.prototype;
target.prototype = new func();
target.prototype.constructor = Target;
}
6:class的继承
es5的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面。 Parent.apply(this) Es6的继承机制完全不同,实质是先将父类实例对象的属性和方法,添加到this上面(所以必须先调用super方法) 然后在用子类的构造函数修改this
class Point {
constructor(name,age) {
this.name = name;
this.age = age;
}
toString() {
return this.name + this.age
}
}
class colorPoint extends Point {
constructor(name,age,sex){
super(name,age) // 调用父类的constructor
this.sex = sex
}
}
class A {
}
class B extends A {
constructor(){
super()
}
}
7:es6的class实现继承的原理
class作为构造函数的语法糖,同时有prototype属性和__proto__属性,因此存在两条继承链
- (1)子类的__proto__属性,表示构造函数的继承,总是指向指向父类
- 子类prototype属性的__proto__属性,表示方法的继承,总是指向父类的prototype
##8: es5继承和es6继承的区别
es5的继承,实质上是先创造子类的实例对象this
然后再将父类的方法添加到this上面
es6的继承机制完全不同,实质是先将父类实例对象的属性和方法加到this上面
(所以必须先调用super方法),然后在用子类的构造函数修改this