javascript原型
- 其他语言一般实现继承是通过class的,但在ECMAScript5中,没有class的。需要通过原型链来实现继承。
- 什么是原型,先来看一段代码
函数F上有一个function F() {} // 函数F上有一个'prototype'属性 console.log(F.prototype); // {constructor: ƒ}
prototype
属性,存放的就是一个对象,该对象就是函数F的原型对象。
在该原型上有一个constructor
属性,指向函数F。当使用new F()
后,会创建一个F的实例f,f上保存的有一个内部属性(在chrome中是__proto__)直接指向F的原型的。
当我们创建了一个函数实例后,去获取实例上的属性时,会现在实例上查找有没有该属性,有的话就返回,没有就继续在原型上查找。例如:
function F(name, age) {
// 在F的实例上添加name属性
this.name = name;
// 在F的原型上添加age属性
F.prototype.age = age;
}
var f = new F('Andy', 23);
console.log(f.name);
// Andy
console.log(f.age);
// 23
// 获取实例f的原型
var f_prorotype = Object.getPrototypeOf(f);
// 删除原型上得的 age属性
delete f_prorotype.age;
console.log(f.age);
// undefined
删除原型上的age属性后,age就变成了undefined
默认的原型
有一个函数F,F的原型就对象Object的实例。所以实际完整的原型如下:
紧接上面的代码,删除f原型上的age属性后
Object.prototype.age = 24;
console.log(f.age);
// 24
因为f的原型就是一个对象,其实就是Object的实例,所以f的原型的原型就是Object的原型。
在搜索f的age属性时,现在实例f上查找,没有找到,继续在f的原型上查找,也没有,再继续在f的原型的原型上搜索,这时就找到了age属性。
所以在查找实例的属性时,是先在实例上查找,没有的话就在实例的原型上查找,还没有的话就会继续在实例的原型的原型上查找,这样一直沿着原型查找,就构成了原型链。如果一直没有该属性,就会一直查找到原型链的末端为止。
以上就构成了原型继承的基础。