原型与原型链
什么是原型、原型链
原型:每一个对象(除null外)都有另一个对象与之相关联,这个另一个对象便称之为“原型”(prototype),每个对象都是从原型继承属性。
原型链:是指一系列链接的原型对象的链称为“原型链”(prototype chain)。
在了解这两个概念之前,先了解三句话:
- 每一个构造函数都有一个原型对象,每一个原型对象都有一个指针constructor指向创建当前对象的构造(初始化)函数。
- 每一个实例都有一个内部指针__proto__,指向原型对象,原型对象上的属性和方法能被实例所访问
- 原型链上的属性和方法能被实例所访问
(函数都有prototype,实例都有__proto__)
另:__proto__是实例和Person.prototype之间的关系,而constructor是实例和Person之间的关系
function Male(){}
var male = new Male();
male.__proto__ -> Male.prototype // -> 表示指向
对于原型链用一种我自己理解的方式表述就是说,通过__proto__来向上查找,最终到Object的__proto__为null。
就是说当前的__proto__指向上一层的prototype,而上一层prototype的__proto__指向上上一层的prototype,以此类推直到最顶层。
一些继承方式
组合继承
用遍历的方法把prototype的方法依次赋给子类的prototype。
Male.prototype = Person.prototype; //会出现地址拷贝(父类能访问子类方法)
//所以使用遍历的方式
for(var i in Person.prototype){
Male.prototype[i] = Person.prototype[i];
call或apply继承
通过call或apply来改变this指向达到继承目的
function Person(name,age){
this.name = name;
this.age = age;
this.sayHello = function(){
console.log(this.name);
}
}
function Male(name,age){ //通过apply改变person里的this指向
Person.apply(this,[name,age])//第一个参数this指本方法里的this
}
function Female(name,age){
Person.call(this,name,age);//通过call改变person里的this指向
}
寄生式继承
通过Object本身的creat方法实现
//Person作为Male的__proto__指向的原型函数存在。
Male.prototype = Object.creat(Person.prototype);
//此时Male.prototype.constructor会指向Person
//所以要将constructor指回Male
Male.prototype.constructor = Male;//constructor:始终指向创建当前对象的构造(初始化)函数。
ES6的继承
通过super来继承
class Person{ //定义父类
constructor(name){
this.name = name;
}
sayHello(){
console.log(this.name);
}
static foo(){ //定义一个静态方法
console.log("foo");
}
}
class Male extends Person{
constructor(name){ //使用super
super(name); //super指向父类的构造函数
this.sexy = "male";
}
sayHi(){
super.sayHello(); //super指向父类的原型对象
}
static bar(){
super.foo(); //super指向父类
}
}
网友评论