JS中的原型与原型链

在JavaScript中,如果我们声明一个变量var a = 1var b = new Number(1)是不一样的,前者会将变量a直接存放在stack(栈)内存中,而后者是在stack中建立一个引用,引用的是heap(堆)内存中的对象,该对象拥有两个key:

Number {1}
__proto__: Number
[[PrimitiveValue]]: 1

其中key:PrimitiveValue的值就是number的值1,今天就重点总结一下对象的另一个key:__proto__

1.原型

如果我们用new的方式创建对象,一般有下面四种数据类型:

1.Number
var n = new Number(1) 创建一个 Number 对象

2.String
var s = new String('hello') 创建一个 String 对象

3.Boolean
var b = new Boolean(true) 创建一个 Boolean 对象

4.Object
var o1 = {}
var o2 = new Object()
o1 和 o2 没区别

创建数据之后,以对象n为例,对象n会拥有诸多方法:

对象n的方法

比如:toString()、toFixed()。
对象n怎么拥有这些方法的呢?
重点就是__proto__ 这个属性,每当我们使用new语法的时候,对象就会拥有__proto__ 这个属性,该属性会指向new之后对应函数(也就是Number)的prototype属性,这个属性是Number共有属性,该共有属性会拥有诸多共有方法,也就是说:

n.__proto__  === Number.prototype
// true

2.原型的原型

仍然以对象n为例,如果对象n的方法在共有的Number属性中找不到,怎么办呢?那么会继续向上一层去寻找,就像数据结构一样。也就是说会向Number.prototype.__proto__中继续寻找,该对象对应的就是另一个对象:Object.prototype。

结果验证

如果还找不到再继续向上一层找呢?那么就是Object.prototype.__proto__,它的值为null,也就是在JS的数据结构中,这是顶层了。
结果验证

结果验证

3.原型链与总结

用一个简答的内存图作为总结:

总结

只要是使用new方法得到的对象,不管是string还是Number或者Boolean,这三种数据类型都有其函数对应的prototype方法,而他们三种数据的prototype方法的上一层(prototype.__proto__)就是object对象的prototype方法。如上图所示。
简单总结为一句代码就是:

var 对象 = new 函数()
对象.__proto__ === 函数.prototype

而.__proto一层一层的指向就可以被称为原型链
由此也可以引出以下几个推论:

// 推论
var number = new Number()
number.__proto__ = Number.prototype
Number.__proto__ = Function.prototype // 因为 Number 是 Function 的实例

var object = new Object()
object.__proto__ = Object.prototype
Object.__proto__ = Function.prototype // 因为 Object 是 Function 的实例

var function = new Function()
function.__proto__ = Function.prototype
Function.__proto__ == Function.prototye // 因为 Function 是 Function 的实例!

参考链接:
1.JavaScript深入之从原型到原型链
2.写代码啦

(完)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容