在js中每个函数(非箭头函数,一般关于原型的有关知识我们都只考虑构造函数)都会拥有一个 prototype 属性,该属性值是一个对象,我们称之为原型对象。原型对象上默认会有 constructor 属性,指向该构造函数。创建原型的主要目的是为了对象实例共享属性和方法。
上面代码中实例对象 p 继承了 Person 原型对象上的方法和属性、如果在创建一个 实例对象同样可以继承该构造函数原型上的属性和方法,实现了数据共享。
每次调用构造函数创造一个新实例,这个实例内部的 [[Prototype]] 指针就会被赋值为构造函数的原型对象。我们可以通过 __proto__ 属性(隐式原型,每个对象都有该属性),访问对象的原型(上面代码有展示出来)。从而实例对象域构造函数之间有了直接的联系。
编辑
原型链:《JavaScript高级程序设计》中的描述是:每个构造函数都有一个原型对象,如果该原型是另一个类型的实例呢?那就意味着这个原型本身有一个内部指针指向另一个原型,相应地另一个原型也有一个指针指向另一个构造函数。这样就在实例和原型之间构造了一条原型链。这就是原型链的基本构想。
在控制台中分析打印出的上面的代码:最外层的对象是 Person.prototype
编辑
上文中我们说到每个对象都有 __proto__,那么原型对象也不例外。
原型链中的查找机制:实例对象上找不到指定属性,就从该原型对象上找,如果还是找不到就到该原型对象上的原型上去找,。逐层查找,直至查找到原型链的顶端 Object.prototype 它的 __proto 值为 null。
不再推荐使用该特性。虽然一些浏览器仍然支持它,但也许已从相关的 web 标准中移除,也许正准备移除或出于兼容性而保留。请尽量不要使用该特性。
当 Object.prototype.__proto__ 已被大多数浏览器厂商所支持的今天,其存在和确切行为仅在 ECMAScript 2015 规范中被标准化为传统功能,以确保 Web 浏览器的兼容性。为了更好的支持,建议只使用 Object.getPrototypeOf()。
注意点:通过现代浏览器的操作属性的便利性,可以改变一个对象的 [[Prototype]] 属性,这种行为在每一个 JavaScript 引擎和浏览器中都是一个非常慢且影响性能的操作,使用这种方式来改变和继承属性是对性能影响非常严重的,并且性能消耗的时间也不是简单的花费在 obj.__proto__ = ... 语句上,它还会影响到所有继承来自该 [[Prototype]] 的对象,如果你关心性能,你就不应该在一个对象中修改它的 [[Prototype]]。
返回指定对象的原型(内部[[Prototype]]
属性的值),参数为要返回其原型的对象。
Object.setPrototypeOf() 方法设置一个指定的对象的原型(即,内部 [[Prototype]] 属性)到另一个对象或 null。
第一个参数是:要设置其原型的对象;第二个参数是:该对象的新原型(一个对象或 null)。
Object.create() 方法用于创建一个新对象,使用现有的对象来作为新创建对象的原型(prototype),返回一个带着指定原型对象的新对象。
前置知识:所有构造函数其实里面都有 prototype 和 __proto__ 这两个属性,所以 Object 和 Function 就是一个构造函数(我的理解)可能不严谨但是对于我们理解这里面的指向问题会很有帮助,为什们会有这句观点?因为之前我在看其他相关的文章解释的时候,一会儿是 Object.__proto__,一会儿又是 Object.prototype,有点绕脑子,所以总结出来了上面的观点。
任何构造函数的 __proto__ 都是 Function.prototype ,所以 构造函数.__proto__ === Function.prototype
实例对象的 __proto__ 指向创建这个实例对象的构造函数,这个知识点大家都应该没得问题
所以 xxx.prototype.__proto__ === Object.prototype,但是这里要注意Object.prototype 这个最顶级的原型对象,不由任何构造函数创建,其 Object.prototype.__proto__ === null
以上就是关于原型及原型链的各种问题,希望能够帮助到大家,还有不明白的可以私信我,或者留言,加油!
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。