js 原型 原型链 基于原型的继承
ECMAScript 标准,符号 obj.[[Prototype]]
用于标识 obj 的原型。
内部插槽 [[Prototype]]
可以通过 Object.getPrototypeOf()
和 Object.setPrototypeOf()
函数来访问。
这个等同于 JavaScript 的非标准但被许多 JavaScript 引擎实现的属性 __proto__
访问器。
==
obj.__proto__
不属于ECMA标准, 标准是通过obj.[[Prototype]]
==来访问原型。只是浏览器普遍采用obj.__proto__
这种实现
ECMA标准 允许以
{ ···, __proto__: xx }
此结构创建对象以声明prototype
构造函数.prototype
只在 new 构造实例时起作用,也就意味着修改构造函数.prototype
只会影响之后构建的实例,而不能影响已构建的实例
JavaScript 中的所有构造函数都有一个被称为 prototype 的特殊属性,它指向原型对象,它与 new
运算符一起使用。
对 原型对象的引用 被复制到新实例的内部属性 [[Prototype]]
中。
也就是说 实例对象的原型对象 与 其 构造函数的 prototype 属性相同
当读取实例对象的属性时,如果自身找不到,则会在原型对象中查找,如果还查不到,则继续向一层原型中查找,一直找到或者出现对象原型为null。
const a1 = new A()
// 在内存中创建对象之后,为其定义 this 并执行 A() 之前,设置 a1.[[Prototype]] = A.prototype。
a1.xx
// 访问实例的属性时,首先检查它们是否直接存在于该对象上,
// 如果不存在,则在 [[Prototype]] 中查找。
// 会递归查询 [[Prototype]]
//
// a1.xx、
// Object.getPrototypeOf(a1).xx、 (a1.__proto__.xx)
// Object.getPrototypeOf(Object.getPrototypeOf(a1)).xx, (a1.__proto__.__proto__.xx)
// 以此类推,直至找到或 Object.getPrototypeOf 返回 null。
构造函数.prototype === Object.getPrototypeOf(对象实例) // `对象实例.__proto__`
Object.getPrototypeOf(Object.prototype) === null
原型链
- js是动态类型,只有一种结构:对象
- 一般的 构造函数 都有
prototype
属性指向 原型对象
*但箭头函数没有默认的原型属性 - 原型对象 本身也是一个对象也有一个自己的原型,层层向上直到一个对象的原型为 null
- 根据定义,null 没有原型,并作为这个原型链(prototype chain)中的最后一个环节。
从这个机制可以看出,对象实际继承了整个原型链条上所有原型对象的属性和方法。
es6 提供的 class属性
ES6 Class
class 属于语法糖,并未改变原本的实现逻辑。js依然是基于原型的。
// 旧的
var Meal = function(food) {
this.food = food
}
Meal.prototype.eat = function() {
return '被吃了'
}
// 新的
class Meal {
constructor(food) {
this.food = food
}
eat() {
return '被吃了'
}
}
Object.create(obj) 不建议使用
除非是为了与新的 JavaScript 特性兼容,否则永远不应扩展原生原型。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· winform 绘制太阳,地球,月球 运作规律
· 上周热点回顾(3.3-3.9)