JavaScript中的原型理解
JS的原型和原型链
函数的prototype
- 每个函数都有一个prototype属性,它默认指向一个Object空对象(即称为:原型对象)
- 原型对象中有一个属性constructor,它指向函数对象
- 给原型对象添加属性(一般是方法),其目的就是使函数的所有实例对象自动拥有原型中的属性(方法)
空对象: 指的是没有属于我们自己的属性
实例加图解
function Fun() {}
console.log(fun.prototype);
给原型对象中增加属于自己的方法
Fun.prototype.getA = function() {}
显示原型和隐式原型
- 每个函数function都有一个prototype,即显示原型
- 每个实例对象都有一个
__proto__
,可称为隐式原型- 对象的隐式原型的值为其对应构造函数的显示原型的值
- 总结:
- 函数的prototype属性:在定义函数是自动添加,默认是一个Object的空对象
- 对象的
__proto__
属性:创建实例对象时,自动添加,默认值为构造函数的prototype属性值- 能直接操作显示原型,但不能直接操作隐式原型(ES6之前)
//对3的验证
function Fun() {} //内部语句: this.prototype = {}
let fun = new Fun() //内部语句: this.__proto__ = Fun.prototype
console.log(fun.__proto__ === fun.prototype) //true
实例内存结构的分析
function Fun() {}
Fun.prototype.test = function() {}
let fun = new Fun()
fun.test()
原型链
访问一个对象属性的顺序:
- 先在自身的属性中查找,如果找到就返回
- 没有找到,在沿着
__proto__
这条链向上查找,找到就返回- 如果最后没有找到,返回undefined
原型链也称为隐式原型链
代码分析
function Fun() {
this.test1 = function() {}
}
Fun.prototype.test2 = function() {}
let fun = new Fun()
fun.test1()
fun.test2()
这里使用了全局函数Object
console.log(Object.prototype === Fun.prototype.__proto__) //true
如果不是很清楚上面这张图,理解下面的代码
//定义一个对象两种情况
let a = {}
let a = new Object()
//在定义函数时,有个内部语句
Fun.prototype = {}
Fun.prototype = new Object()
//所以
console.log(Object.prototype === Fun.prototype.__proto__) //true
特殊情况
考虑Object()
和 Function
这两种情况,有点特殊
function Foo() {} //Foo有显示原型属性
let Foo = new Functioin() //Foo有隐式原型属性
//对于Object也一样
这里我就不仔细的画图了,如果想要弄明白,可以自己跟着上面的思路研究下,这样更有利于对原型的理解哟。。。