1. 原型的定义
函数的prototype属性
- 每个函数都有一个prototype属性,它默认指向一个Object空对象(即原型对象)
- 原型对象中有一个属性constructor,它指向函数对象
// 注释后为输出结果
// 每个函数都有一个prototype属性,它默认指向一个Object空对象(即原型对象)
// 自定义函数
function Fn() {
}
console.log(Fn.prototype); // {}
// 预设函数
console.log(Date.prototype, typeof Date.prototype); // {} object
// 原型对象中有一个属性constructor,它指向函数对象
console.log(Fn.prototype.constructor == Fn); // true
console.log(Date.prototype.constructor == Date); // true
// 给原型对象添加属性(一般是方法)===>实例对象可以访问
Fn.prototype.test = function() {
console.log("test");
}
var fn = new Fn();
fn.test(); // test
1.1 显式原型与隐式原型
-
每个函数function都有一个
prototype
,即显式原型(属性) -
每个实例对象都有一个
__proto__
,可称为隐式原型(属性) -
对象的隐式原型的值为其对应的构造函数的显式原型的值
function Fn() { // 相当于内部执行语句:this.prototype = {}
}
// 1.每个函数function都有一个prototype,即显式原型
console.log(Fn.prototype); // {}
// 2.每个实例对象都有一个`__proto__`,即隐式原型
var fn = new Fn(); // 相当于内部执行语句:this.__proto__ = Fn.prototype
console.log(fn.__proto__); // {}
// 3.对象的隐式原型的值为其对应的构造函数的显式原型的值
console.log(fn.__proto__ === Fn.prototype); // true
其内存分析如下图所示:
2. 原型链
定义:当对象找不到需要的属性时,它会到这个对象的子对象上去找,以此类推,这就构成了对象的原型链。并且Object.prototype是对象的最终原型,绝大多数对象最终都会继承自Object.prototype,而Object.prototype的原型是null。
function Fn() {
this.test1 = function() {
console.log('test1');
}
}
Fn.prototype.test2 = function() {
console.log('test2');
}
var fn = new Fn();
fn.test1();
fn.test2();
console.log(fn.toString());
其内存分析为: