瞎写的原型理解

原型与原型链的基础定义理解

关于原型与原型链下面这些基础 JavaScript 知识一定要 “死记硬背” 的。只有 “死记“,才能 “用活”。

  1. 对象是某个特定引用类型的实例,可以理解为对象要通过构造函数实例化实现的,而构造函数本身又是一个对象,构造函数本身又需要通过构造函数实例化实现。
  2. JavaScript 提供了很多原生引用类型:Object、Array、Function、String、Number、Boolean、Date、RegExp,Map、WeakMap、Set、Symbol、BigInt 同时它们也都是原生构造函数
  3. 每个函数都是 Function 类型的实例,因此函数也是对象,所以同时拥有 __proto__prototype属性
  4. 对象都拥有隐式原型(__proto__ 属性)指向它的构造函数的原型对象(prototype 属性)
  5. 每个构造函数都有一个 prototype 属性,叫原型对象(注意:原型对象,本质是对象),也叫显式原型
  6. 原型对象上有一个 constructor 属性指向构造函数本身
  7. 通过 new 实例化出来的对象没有 prototype 属性
  8. 对象都具有 __proto__ 属性
  9. 宇宙的尽头:Object.prototype.__proto__ === null
  10. 对象的constructor 属性用于返回创建该对象的函数

注意:并不是所以的prototype属性都是对象 Function.prototype是一个函数 它的__proto__属性又指向Object.prototype

typeof Function.prototype // 'function'

上面的规则 1、2、3 结合一起理解。
我们知道对象是可以这样实现的 const obj = new Object() 那么 obj 就是引用类型 Object 的实例,也就是说 obj instanceof Object 为 true,而 Object 又是原生构造函数,即 typeof Object === "function",每个函数都是 Function 类型的实例,也就是 Object 也是 Function 的实例,即 Object instanceof Function 为 true

通过原型与原型链进行理解。

const obj = new Object() ,那么根据上面的规则 4 和 5 可以得知,obj.__proto__ === Object.prototype 根据规则 2、3、4 可以知道 Object 本身是引用类型也就是对象,根据规则 8,Object 拥有隐式原型 proto 同时 Object 也是一个函数,而函数都是 Function 的实例,也就是 Object 是 Function 的实例,因为对象的隐式原型(proto 属性)指向它的构造函数的原型对象(prototype 属性) 所以:Object.__proto__ === Function.prototype,根据上面的规则 5,Function.prototype 本质是对象,根据规则 8,Function.prototype 拥有隐式原型 __proto__,而对象是通过原生构造函数 Object 实现的,所以 Function.prototype.__proto__ === Object.prototype,最后根据规则 9,Object.prototype.__proto__ === null

至此,这整一个链路的过程也就是原型与原型链的原理解析过程,本质就是通过属性 __proto__ 进行链接每一个节点对象。

每个函数都是Function的实例

上面的规则 3:每个函数都是 Function 类型的实例,因此函数也是对象。

function fn(){}
fn.__proto__ === Function.prototype //true
Object.__proto__ === Function.prototype //true
String.__proto__ === Function.prototype //true
Number.__proto__ === Function.prototype //true
Array.__proto__ === Function.prototype //true

Function 自己也是 Function 的实例,首先通过上文我们已经可以得知:

typeof Function === 'function' // true
Function instanceof Function === true // true
Function.__proto__ === Function.prototype //true

constructor

根据规则10可以知道,对象的constructor 属性用于返回创建该对象的函数;

let obj = new Object()
obj.constructor === Object  //true

let Star = function(){}
let s = new Star()
s.constructor === Star //true

// 根据规则3可以知道,每个函数都是 Function 类型的实例,因此函数也是对象,所以同时拥有 __proto__和prototype属性
Array.constructor === Function //true
Object.constructor === Function //true
Number.constructor === Function //true
String.constructor === Function //true

原型

  • prototype 一般称为显式原型,__proto__一般称为隐式原型。每一个函数在创建之后,在默认情况下,会拥有一个名为 prototype 的属性,这个属性表示函数的原型对象。除此之外,每个 JavaScript 对象都有一个隐藏的原型属性——__proto__
  • 原型对象的作用就是用来存放实例对象的公有属性和公有方法。在使用构找函数实例化的时候,会重复创建一次相同的属性和方法,属于代码的冗余。所以把共用属性和方法放在原型对象里共享
function Fn() {}
const obj = new Fn()
// 对象 obj 的隐式原型指向构造函数 Fn 的原型对象
obj.__proto__ === Fn.prototype //true

原型链

1.当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。
2.如果没有就查找它的原型(也就是__proto__ 指向的prototype原型对象) .
3.如果还没有就查找原型对象的原型( Object的原型对象) .
4.依此类推一-直找到Object为止( null) .
5.__proto__ 对象原型的意义就在于为对象成员查找机制提供-个向,或者说一条路线

原型链查找规则:首先看自身对象上是否有这个属性,如果有就直接返回;如果没有就会沿着__proto__这个隐式原型往上查找,也就是去构造函数的原型对象prototype身上查找

 function Star(uname,age){
   this.uname = uname
   this.age = age
}
Star.prototype.sing1 = function(){
      console.log('sing1')
}
Object.prototype.sing2 = function(){
      console.log('sing2')
}
let ldh = new Star('ldh',18)
ldh.sing1() //sing1
ldh.sing2() //sing2

在这里插入图片描述
部分内容转载与https://juejin.cn/post/7129157532970385421

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值