由来
js是基于原型的语言,没有类的概念,为了描述联系对象和对象之间的关系就有了原型和原型链。
原型
原型(prototype)就是模板,本质也是一个对象,它定义了构造函数构造出来的对象可以继承该原型的属性和方法,用于表示对象之间的关系。每个函数都有一个prototype属性,这个属性指向的就是原型对象;实例上有一个__proto__指向它的构造函数的原型对象。
特点
prototype只有函数有,对象没有
原型链
定义
每个对象上拥有一个__proto__属性指向原型对象,对象以其原型为模板,从原型继承方法和属性。原型对象也可能拥有原型,并从中继承方法和属性,一层一层,以此类推,这种关系被称为原型链。
作用
利用原型让一个引用类型继承另一个引用类型的属性和方法。
特征
-
当访问一个对象的属性时,如果自身为未找到,会通过自身的__proto__属性找到原型对象,如果原型对象也不存在该属性,会沿着原型对象的__proto__继续向上查找,一直找到Object.getPrototypeOf(obj)===null
-
原型对象上的方法是被不同实例共有的,当我们修改原型时,与之相关的对象也会被改变。
面试题
- a是如何通过原型链找到的null
var a = new Number();
a.__proto__=== Nember.prototype
Nember.__proto__ === Function.prototype
Function.__proto__ === Function.prototype
Function.prototype.__proto__ === Object.prototype
Object.prototype.__proto__ === null
Function.__proto__ === Function.prototype
// 因为Function.prototype是对象,所以指向Object的原型
Function.prototype.__proto__ === Object.prototype
- 请写出上面编程的输出结果是什么?
var F = function() {};
Object.prototype.a = function() {
console.log('a');
};
Function.prototype.b = function() {
console.log('b');
}
var f = new F();
f.a(); // a
f.b(); // 报错,不存在b方法
F.a(); // a
F.b(); // b
解题过程
// f.a()
1) 实例上没有a,去它的构造函数F的原型上上去找,也就是F.prototype
2) F.prototype上也没有a,然后顺着F.prototype.__proto__找到Object.prototype
// F.a()
1) F上没有a,去它的构造函数Function的原型上找,也就是Function.prototype
2)Function.prototype上也没有,就顺着Function.prototype.__proto__找到Object.prototype
小结
- Object是所有对象的爸爸,所有对象都可以通过__proto__找到它
- Function是所有函数的爸爸,所有函数都可以通过__proto__找到它
- 函数的prototype是一个对象
- 对象的__proto__属性指向原型,__proto__将对象和原型连接起来组成原型链