05|原型链:V8是如何实现对象继承的?
该思维导图由 AI 生成,仅供参考
- 深入了解
- 翻译
- 解释
- 总结
V8引擎在JavaScript中实现对象继承的方式是基于原型链的设计。与基于类的继承不同,JavaScript的继承机制通过每个对象都包含一个原型属性,指向原型对象,从而实现继承特性。通过原型链,对象可以访问其原型对象的属性和方法,形成了一种简洁而优美的继承方式。文章还介绍了利用`__proto__`属性实现继承的实践方法,以及通过构造函数创建对象的过程。通过`new`关键字配合函数,JavaScript虚拟机会返回一个对象,实现了对象的创建。整体而言,本文深入浅出地介绍了V8引擎是如何实现JavaScript中的对象继承,以及原型链的工作原理,为读者提供了清晰的技术概览。文章还回顾了JavaScript的历史,解释了为何JavaScript中使用了`new`关键字来创建对象,以及其与Java的关系。通过讲解构造函数实现继承的方式和`new`关键字的历史,读者可以更好地理解JavaScript中的继承机制。
《图解 Google V8》,新⼈⾸单¥59
全部留言(39)
- 最新
- 精选
- 张青天DogFactory 是 Function 构造函数的一个实例,所以 DogFactory.__proto__ === Function.prototype DogFactory.prototype 是调用 Object 构造函数的一个实例,所以 DogFactory.prototype.__proto__ === Object.prototype 因此 DogFactory._proto_ 和 DogFactory.prototype 没有直接关系
作者回复: 没问题
2020-03-266110 - 搞学习推荐一篇挺好的文章,结合老师讲的一起看有奇效 https://juejin.im/post/5cc99fdfe51d453b440236c3
编辑回复: 优秀
2020-03-2627 - sugar老师,这几节课看了有关对象,函数这些东西在v8的实现,感觉还不过瘾,想问下老师能否把文中提到的一些v8的实现思路,在文末增加一个链接直接跳转到v8的c++源代码里 具体到文件和行号?
作者回复: 这个专栏定位还是给前端工程师的,所以根本没打算讲源码,源码比想象的复杂太多,光一个原型的实现就做了很多复杂的优化!比如通过隐藏类优化了很多原有的对象结构,所以通过直接修改—proto—会直接破坏现有已经优化的结构,造成严重的性能问题! 另外比如讲作用域的C++实现我觉得也没太大意义,有能力看代码的人结合文档和流程就可以直接去看代码了! 比如编译流程,代码的文档结构 在v8.dev中都有介绍.
2020-03-26710 - 若川关于思考题,我以前写了一篇文章《面试官问:JS的继承》画了一张图可以很好的回答这个问题。 https://user-gold-cdn.xitu.io/2019/2/18/169014cf74620047?imageslim (极客时间评论不支持图片。只好放个图片链接了) 文章链接 https://juejin.im/post/5c433e216fb9a049c15f841b
作者回复: 很赞
2020-05-318 - mfistDogFactory.prototype 是Dog工厂函数实例对象的原型链(```dog = new DogFactory()```),dog实例上面没有属性或方法会去原型链上面寻找。 DogFactory.__proto__ 是函数对象的原型链 ,```function DogFactory(){} ``` 另外一种类似实现是 ```DogFactory = new Function([arg1, arg2] functionBody)``` 所以它应该指向Function.prototype。引用MDN一句话: Function对象继承自Function.prototype属性,它是不能被修改的。``` Function.prototype.toString() 得到 "function () { [native code] }"``` 所以两者是有本质区别的。要说有啥关联性的话,就是```DogFactory.prototype.constructor ===DogFactory // true``` DogFactory.prototype上面构造函数就是 DogFactory 今日总结 1. 普通对象上面有一个隐藏的__proto__对象,指向自己的原型。当在对象上面访问属性的时候会先在当前对象寻找,如果找不到再去原型链上面寻找。 2. javascript为了蹭到当时java的热度和迎合java程序员,起名为javascript,和模仿了 new Foo() 创建对象的语法(虽然和面向对象创建实例的底层逻辑完全不一样) ``` function Foo(){ this.name = 'foo' this.label = 'function' } const foo = new Foo() // new Foo执行的内部逻辑如下 let obj = {} obj.__proto__ = Foo.prototype let args = [...arguments] let result= Foo.call(obj, args) if (typeof result === 'object'){ return result } return obj ```
作者回复: 赞
2020-03-268 - tomision直接使用 __proto__ 属性,会有严重的性能问题。这个点可以详细说说嘛?
作者回复: 隐藏类的优化措施优化过了对象,修改了proto的属性指向,相当于要重建整个隐藏类,必然会影响性能
2020-03-264 - 伪装Null 设计的初衷是什么 它具体担任了什么样的角色
作者回复: 最初NULL就代表是空,比如Number(null),就会返回一个0,可以把null看成是c中或者java中的null。 可以根据一个值是否是null,来判断做什么事情。 但是javascript同时支持原生类型和对象类型,null是一个对象,那么发明者认为,对象和原生类型进行默认转换,会造成很多误解,并且不容易发现错误,那么又设计了一个undefined,用来表示未使用的原始值,转换为数值时为NaN! 总的来说,这个设计糟糕的一塌糊涂,但是我们依然得使用它们 还需要一个类型来表示原生类型的
2020-05-253 - 墨灵``` const someFactory = (key) => { this.key = key } ``` 试问,someFactory能否成为一个构造函数? 答案是不能,箭头函数在js里也是一个比较特殊的存在,根本没是prototype的属性,自然也没有constructor
作者回复: 赞
2020-03-293 - 盖世英雄每个函数对象中都有一个公开的 prototype 属性,当你将这个函数作为构造函数来创建一个新的对象时, 这句话中: 都有一个 公开的 prototype属性,‘公开的‘ 是不是写错了? 上文还提到 prototype属性是隐藏的呢?还是我理解的不对呢?
作者回复: —proto—是隐藏属性,prototype可是标准定义的
2020-03-263 - 七月有风class 中的方法为什么要放在构造函数prototype上。而不是放在构造函数中?
作者回复: 放在prototype属于全局的,只要继承了prototype的类都可以共同拥有该方法,放在构造函数中就属于当前对象了,具体放在什么地方要看具体需求了
2020-04-082