、怎么用、要怎么避坑,让你看完就能用起来。
一、从一句最常用的代码说起
在 JavaScript 的日常开发中,原型和原型链无处不在。按理说,很多时候,我们还没有意识到,就已经受益于原型带来的便利。
举个例子,你随手声明一个数组:
const array =;
无需任何额外声明,你就可以直接在 array 上调用各种方法:
array.find;说起来,// array.sort;// array.join;// ",,,,"
这些 findsortjoin 方法是从哪里来的?你并没有在 array 对象上定义它们,它们却可以直接使用。答案就是痛点:为什么数组对象本身没有这些方法却能调用?这背后隐藏着什么机制,
二、一张图理解 prototype 和 __proto__这个奇葩命名规则是怎么来的?
-
构造函数:一个普通的函数,比如 function Product { this.name = name;},首字母大写只是约定,
-
关系?
-
__proto__:每个对象都有一个内部属性指向它的原型。对于实例对象p.__proto__ === Product.prototype。
三、日常实战:原型链能帮我们做什么?解决那些具体问题,
. 方法借用——让 NodeList 也能用 map
{}
. 安全判断类型——不再被 typeof null戏弄
. 创建纯数据字典——Object.create
. 配置继承——不破坏默认配置的优雅方式
-
"作为前端开发者最想知道的是:我平时写代码中哪些操作是在使用原型链机制?- 数组/字符串/对象等内置类型方法调用
- new关键字创建实例时发生了什么
- extends/class关键字背后做了什么
- Object.create与new操作有何不同"
- 原始值与包装器对象之间如何转换?
- 原始值与包装器对象之间如何转换?说起来,- 原始值与包装器对象之间如何转换?话说回来,- 原始值与包装器对象之间如何转换?
-
- hasOwnProperty vs in运算符
- Object.getOwnPropertyNames
-
在Vue/React项目中经常需要深拷贝数据以避免状态污染问题:
JSON.parse)存在哪些潜在风险?深拷贝库如lodash.cloneDeep底层怎么处理引用类型和特殊类型?话说回来,
-
为何有些库会显式检查instanceof而非typeof?话说回来,instanceof检查时会沿着整条原形链向上搜索吗?如果父类prototype被修改了会影响instanceof判断吗?
javascript
// 常见错误示例
function createInstance{
const instance = {};instance.__proto__ = Parent.prototype;// 不推荐,其实,直接操作隐式属性危险
Parent.call;return instance;}
// 推荐写法使用Object.create
const instance = Object.create;mermaid
graph TD;A --> B
B --> C
C --> D] "]
D --> E] "]
E --> F
G --> H] "]
H --> E
style A fill:#f9f,stroke:#f99,stroke-width:.75pt,stroke-dasharray:.7 .7 .7 .7 .7 .7 .7 .7,.7 .7 .7,.7.7.7.7.7.7,.666666666,.999999,.444,.333,.222,.2,.8888,fill-opacity:.8,text-align:center,text-opacity:.6,shape-circle,radius-.6rem,border-radius-.4rem,border-style-solid,border-width-.4rem,border-color-pink,padding-.4rem,box-shadow-blur-invert-spread-offset-inset-x-y-rgba,hsl,-deg%,%%。%
python
# Python等其他语言中通常通过以下方式模拟JS中的]过程:
class JSValue:
def __init__:
self._properties_own_={}
self._properties_proto_={}
def __getattr__:
if name in self._properties_own_:
return self._properties_own_
elif self._properties_proto_.get: # 检查是否有显式设置__proto__
return getattr
至于else,raise AttributeError
def __setattr__:
if name=='_properties__':
super.__setattr__
else的观点是,self._properties_own_=value
obj_a=JSValue
obj_a.color='#FF'
print# 输出#FF # 自身属性优先访问
obj_b=JSValue
obj_b.__proto__=_=obj_a # 在Python中通过duck typing模拟JS中的显式设置行为print) # 输出#FF # 原形链访问`
。