js 原型 原型链 基于原型的继承

MDN 继承与原型链
参考博客
简单易懂的视频

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 属性
new 构造
constructor 属性
Object.getPrototypeOf
Object.getPrototypeOf
Object.getPrototypeOf
Constructor构造函数 / Class类
[[Prototype]] 原型
obj 实例对象
···
null // Object.prototype.__proto__
构造函数.prototype === Object.getPrototypeOf(对象实例)  // `对象实例.__proto__`  

Object.getPrototypeOf(Object.prototype) === null

原型链

  1. js是动态类型,只有一种结构:对象
  2. 一般的 构造函数 都有 prototype 属性指向 原型对象
    *但箭头函数没有默认的原型属性
  3. 原型对象 本身也是一个对象也有一个自己的原型,层层向上直到一个对象的原型为 null
  4. 根据定义,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 特性兼容,否则永远不应扩展原生原型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值