【你不知道的JavaScript】(07)原型

本文章仅针对我自己在看书过程中对一些不太清楚的知识点进行查漏补缺——《你不知道的JavaScript(上卷)》第二部分this和原型中的第5章”原型“

原型概念

JavaScript中每个对象都有一个特殊的内置属性prototype,这个特殊的对象可以指向另一个对象

触发[[get]]操作时,如果在对象上没有找到需要的属性或者方法引用,引擎就会继续在 [[Prototype]] 关联的对象上进行查找

获取原型的方式

  1. 通过对象的__proto__属性可以获取到(早期浏览器自己添加的,存在一定的兼容性问题)

  1. 通过Object.getPrototypeOf方法

prototype与__proto__

prototype

特点:所有函数都有prototype属性,而对象没有

函数的prototype中有属性constructor,这个属性指向函数,即

function fn(){}
fn.prototype.constructor === fn

也可以嵌套循环调用 【fn.prototype.constructor.prototype.constructor...】

__proto__

特点:所有的对象都有__proto__属性,当然也包括函数

new关键字创建一个变量发生了什么

function Person() {}
var p = new Person();
// 上面的操作相当于会进行如下的操作

// 1. 创建一个全新的变量
p = {}
// 2. 函数的显示原型会赋值给这个对象的隐式原型
p.__proto__ = Person.prototype
// 3. 这个新创建的对象绑定到函数调用的this上
// 4. 执行函数
// 5. 如果函数没有返回值,便返回这个新创建的秀

一张图了解普通函数、Function、Object 与它们创建的对象、它们的原型对象之间的关系

function Foo() {}

new Foo().__proto__ === Foo.prototype
new Function().__proto__ === Function.prototype
new Object().__proto__ === Object.prototype

Foo.__proto__ === Function.prototype
Function.__proto__ === Function.prototype
Object.__proto__ === Function.prototype

Foo.prototype.__proto__ === Object.prototype
Function.prototype.__proto__ === Object.prototype
Object.prototype.__proto__ === null

原型链的尽头——Object的原型

Object.getPrototypeOf({}) // [Object: null prototype] {}
Object.getPrototypeOf(Object.getPrototypeOf({})) // null

原型链的作用

访问变量或方法

本质:触发[[get]]操作时,先找这个对象上,没有就找原型对象

例子:for in 、 in 、 a[key]、a.key

复杂情景
myObject.foo = "bar";
  1. myObject对象包含foo属性(writable为true),修改已有的foo属性值,无论原型链上是否有

  1. foo不存在于myObject中,遍历原型链,如果原型链上没有该属性,则赋值到myObject上

  1. foo不存在于myObject中,存在于其原型链上

  1. 没有被标记为只读,直接在 myObject 中添加一个名为 foo 的新属性

  1. 只读,严格模式下报错,非严格模式这条赋值语句不起作用

  1. 有setter,则调用这个setter,foo不会被添加到myObject上,也不重新定义setter

继承

Object.create(o)

作用:创建一个新对象并把它关联到我们指定的对象

原理:借用构造函数实现继承

实现:

if (!Object.create) {
  Object.create = function (o) {
    function F() {}
    F.prototype = o;
    return new F();
  };
}

拓展:如果仅仅想要处理方法或者属性未找到时的场景,可以使用Proxy

Object.setPrototypeOf(o1, o2)

作用:

原理:相当于直接设置隐式原型,即o1.__proto__ = o2

应用——vue中的inject/provide

vue中的inject与provide提供了一种后代与祖先组件的通信方式

provide(key, value)提供一个值,可以被后代组件引用

inject(key)用来访问祖先组件提供的值,沿着父组件链查找,这个父组件链的实现就是原型链

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值