javascript中__proto__和prototype的区别
文章目录
prototype是函数特有的属性,一个对象的构造函数也是函数,js中没有类,只有构造函数。关于原型链的继承在这里不展开。
__proto__
属性已经被标记为deprecated,可以用Object.getPrototypeOf(obj)
的方式代替访问该属性,应该避免修改该属性,因为它会影响到所有跟这个属性有关的对象,性能非常低下,可以用Object.create(targetproto)
的方式直接用你希望的原型创建一个新的对象。
本文以下内容仍以__proto__
的方式表示该属性,主要为解释原理,在生产中应该避免使用
__proto__
是对象上的属性,而js中一切皆对象,访问__proto__
属性等同于访问该对象的构造函数的prototype
属性,对于一个普通的构造函数及通过其构造的对象,这一点不难理解,在console中测试:
|
|
Object和Function
相比于上面的普通对象和构造函数,Object
和 Function
比较难理解,在浏览器点开console,输入Object.prototype
,在输出中随便找点点击一个函数,如toString()
,里面有个__proto__
,再点进去,里面还有个__proto__
,再点进去,里面的内容跟刚才Object.prototype的输入里一样的,如此循环下去。。。
想搞清楚这些,先明确几个概念:
- js中一切皆对象,person1是对象,其构造函数Person也是对象,Object,Function都是对象。所有对象的原型链尽头都是
Object.prototype
。对象的原型链:person1 -> Person.prototype -> Object.protoytpe -> null
,这其中的每一环,如Person.prototype
也都是对象,所有对象不断的访问__proto__
属性,都会返回自己的原型链上游,只有一个例外,Object.prototype.__proto__===null
- 所有函数对象的构造函数都是
Function
,所有函数对象的原型都是Function.prototype
。 - 一切构造函数是对象的同时,也是函数。
Object
和Function
,既是对象又是构造函数。 - 原型
Function.prototype
也是对象,其原型链上游为Object.prototype
。
如构造函数Person
,Person.__proto__===Function.prototype
返回true,这里的Person可以理解为一个对象:一个从Function.prototype
这个原型继承而来的对象。
在console中运行下面的代码来验证上述的原型之间的关系:
|
|
回到上面无限循环的例子,对应每一步解释:
- 在console输入
Object.prototype
时,返回的是所有对象的原型链顶端的Object.prototype`对象,里面有一些方法 - 点击
toString()
方法,该方法本质是函数,所有的函数对象的原型都是Function.prototype
,即toString().__proto__===Function.prototype
,所以点开__proto__
就是Function.prototype
对象 Function.prototype
对象也是对象,它的原型就是Object.prototype
,即Function.prototype.__proto__===Object.prototype
,所以点开__proto__
又回到了1,无限循环。
版权声明 本博客使用CC BY-NC-SA 4.0许可协议(创意共享4.0:保留署名-非商业性使用-相同方式共享)。