原型
1. 函数的prototype属性
* 每个函数(Function)都有一个prototype属性, 它默认指向一个空的Object实例对象(即称为: 原型对象)
* 原型对象中有一个属性constructor, 它指向函数对象
console.log(Date.prototype)
console.log(Date.prototype, typeof Date.prototype) // 'object'
console.log(Date.prototype.constructor === Date) // true
2. 给原型对象添加属性(一般都是方法)
* 作用: 函数的所有实例对象自动拥有原型中的属性(方法)
function Fn() {
}
//给原型对象添加属性(一般都是方法)
Fn.prototype.test = function () {
console.log('test()')
}
var fn = new Fn()
fn.test()
显示原型与隐士原型
1. 每个函数function都有一个prototype,即显式原型
2. 每个实例对象都有一个__proto__,可称为隐式原型
3. 对象的隐式原型的值为其对应构造函数的显式原型的值
内存结构(图):
5. 总结:
* 函数的prototype属性: 在定义函数时自动添加的, 默认值是一个空Object对象(空对象不是什么都没有,而是没有自定义的东西)
* 对象的__proto__属性: 创建对象时自动添加的, 默认值为构造函数的prototype属性值
* 程序员能直接操作显式原型, 但不能直接操作隐式原型(ES6之前)
另外说明:
执行函数: 执行函数体中的所有语句
执行函数定义: 本质是创建函数对象,没有执行函数体语句
原型链
访问一个对象的属性时,
* 先在自身属性中查找,找到返回
* 如果没有, 再沿着__proto__这条链向上查找, 找到返回
* 如果最终没找到, 返回undefined ,Object原型对象的__proto__的值是null
console.log(Object.prototype.__proto__); // null
var obj=new Object();
console.log(obj.__proto__.__proto__); // null
* 别名: 隐式原型链
* 作用: 查找对象的属性
在我们自己写的代码还没执行之前,js引擎会加载一些类似代码,加载了function Object(value){ }函数定义,执行完后内存栈中有Object变量(引用类型),指向堆空间的一块内存(Object函数对象),Object函数对象默认有显示原型prototype属性,prototype它是引用类型属性,存地址值,指向堆空间另一块内存(Object原型对象)
原型链内存图: