JS 中 proto 和 prototype 存在的意义是什么?
有许多人多这两个概念很模糊。今天就来重点探讨。
在开始之前我们要明确一点,js
代码在开始运行之前,js
运行环境中就已经有window
对象了,window
对象有一个Object
属性,window.Object
是一个函数对象。当然window
不止有这一个属性,还有其他的属性 ,现在需要画图了解一下 ,记住一点,要想真正的理解原型链,画图必不可少。
你的 JS 代码还没运行的时候,JS 环境里已经有一个 window 对象了window 对象有一个 Object 属性,window.Object 是一个函数对象window.Object 这个函数对象有一个重要属性是 prototype,干什么用的等会说window.Object.prototype 里面有这么几个属性 toString(函数)、valueOf(函数)
上面的图比较抽象 ,我们继续 ,上面window属性都是浏览器内置好的
记住函数也是对象
他们都拥有一个共同的特点: 都有一个prototype的对象!
如何访问呢?
很简单
window.Object.prototype,
window.Array.prototype
.......
这里的window可以省去不写
Object.prototype (简写)
下面看代码:
var obj = {}
obj.toString();
这一行代码做了什么?
为什么能直接调用obj.toString方法呢?
重点来了 !!!这就牵扯到原型链了,在写函数的时候不可能把所有的函数都实现一遍,而浏览器厂商已经内置好了,放在那里了呢?看就在这里
obj
怎么访问呢?其实obj有个重要的属性_proto_
直接指向Object.prototype
看着不明显 再看下面这幅图:
再看下面这个例子 加深印象 .
var a = []
a.toString()
a.valueOf() 自己的原型上面没有,就回去Object.prototype去找!
这行代码执行什么 ?
a
自身没有这些方法,a._proto_
指向了Array.prototype
原型.于是乎继承了这些属性。
它有指向了Array.prototype
,
对象之源
重点来了,所有对象都可以使用Object.prototype
可以称它为对象之源!!!a
在这里虽然声明的是一个数组,但它也是一个对象,所有对象都可以使用Object.prototype
探讨一下,a
可以调用自己的原型Array.prototype
,也可以调用Object.prototype
原型,当自身的原型没有这个属性的时候,就回去Object.prototype
原型去找,具体如下:
具体找的过程请看下图!
总结:proto是对象用来保存原型的地址
原型链:通俗来说就是一个函数的可用范围。