美文网首页
JS原型链模式

JS原型链模式

作者: 空压机百科 | 来源:发表于2019-12-08 02:51 被阅读0次

构造函数模式中拥有了类和实例的概念,并且实例和实例之间是相互独立开的即实例识别。
基于函数的原型模式解决了方法和属性公有的问题,把实例之间相同的属性和方法提取成公有的属性和方法。

每一个函数数据类型(普通函数,类)都有一个自带属性:prototype(原型),且这个属性是一个对象数据类型的值(浏览器会开辟一个堆内存)。并且在 prototype 上浏览器给它加了一个属性 constructor(构造函数),属性值是当前函数(类)本身。每一个类都把供实例调取的公共属性方法存储到自己的原型上。
每一个对象数据类型(普通对象,实例,数组,正则,Math,prototype...)也自带属性:__proto__,属性值是当前实例所属类的原型(prototype),不过不确定是谁的实例都是Object的实例
案例图解:

function Fn(){
   this.x = 100;
   this.y = 200;
   this.getX = function (){
      console.log(this.x);
   }
}
Fn.prototype.getX = function(){
   console.log(this.x);
}
Fn.prototype.getY = function(){
   console.log(this.y);
}
var f1 = new Fn;
var f2 = new Fn;
原型链内存图

Object 是 JS 中所有对象数据类型的基类(最顶层的类)
1、f1 instanceof Object 为 true 是因为 f1 通过__proto__可以向上级查找,不管有多少级最后总能查找到 Object。
2、在 Object.prototype 上没有__proto__这个属性

原型链模式:

f1.hasOwnPrototype("x") // hasOwnPrototype 是 f1 的一个属性
但是 f1 的私有属性上并没有这个方法,那该如何处理呢?
a、通过“对象名 . 属性名”的方式获取属性值的时候,首先在对象的私有的属性上进行查找,如果私有中存在这个属性,则获取的是私有的属性值;如果私有作用域没有,则通过__proto__找到所属类的原型(类的原型上定义的属性和方法都是当前实例公有的属性和方法),原型上存在的话, 获取的是公有的属性值;如果原型上面也没有,则继续通过原型上的__proto__向上查找,一直找到Object.prototype为止...
这种查找机制就是我们的“原型链模式”

在原型模式中,this 常用的两种情况:
a、在类中的 this.xxx = xxx;this 当前类的实例(this博客中第4种)
b、在某个方法中的 this 看执行的时候 “.” 前面是谁 this 就是谁(this博客中第1种)。注意:
需要先确定 this 的指向(this 是谁),把 this 替换成对应的代码,按照原型链查找机制,一步步查找结果。
案例:

function Fn(){
   this.x = 100
   this.y = 200
   this.getY = function(){
      console.log(this.y)
   }
}
Fn.prototype = {
   constructor: Fn   // 如果不设置 constructor: Fn 那么它的指向就不是 Fn 而是 Object
   y: 300
   getX: function(){
      console.log(this.x)
   }
   getY: function(){
      console.log(this.y)
   }
}
var f = new Fn();
f.getX();  // this 是 f   console.log(f.x) == 100
f.__proto__.getX()  // this 是 f.__proto__   console.log(f.__proto__.x) == undefined
Fn.prototype.getX()  // this 是 Fn.prototype   console.log(Fn.prototype.x) == undefined
f.getY()  // this 是 f    console.log(f.y)  == 200  
f.__proto__.getY()  // this 是 f.__proto__   console.log(f.__proto__.y)  ==  300
批量设置原型上的公有属性和方法:重构原型对象的方式
function Fn(){
   this.x = 100
}
Fn.prototype = {
   constructor: Fn
   a: function(){},
   b: function(){}
}

1、只有浏览器天生给 Fn.prototype 开辟的堆内存里有 constructor,而我们自己开辟的这个堆内存没有这个属性,这样 constructor 指向就不是 Fn 而是 Object 了。为了和原来的保持一直需要手动添加 constructor 的指向
2、内置类增加公有属性只能在原型上增加方法且方法名不能和内置的重复,例如:

Array.prototype.myname = function(){console.log("ok")}

如果使用重构的方法(设置 constructor: Array)会把之前的已经存在于原型上的属性和方法替换掉,所以浏览器会把这种方法屏蔽掉

for in 循环遍历的时候,默认可以把私有的和它所属原型上扩展(自己添加)的属性和方法都可以遍历到,一般情况下遍历一个对象只需要遍历私有的即可。可以使用两种方法处理:

Object.prototype.aaa = function(){}
var obj = {nane: "小明", age: "18"}
for(var key in obj){  
  // if(obj.propertyIsEnumerable(key)){  // 第一种方法
      // console.log(key) 
   // }
   if(obj.hasOwnProperty(key)){
      console.log(key) 
   }
}

Object.create(proObj) 创建一个新的对象,但还是要把 proObj 作为这个对象的原型

var obj = {
   getX: function(){}
}
var obj2 = Object.create(obj)

”原型继承“是 JS 中最常见的一种继承方式,子类想要继承父类中所有的属性(私有属性和公有属性),只需要让”子类.prototype = new 父类“即可。
原型继承特点:是把父类中的私有属性和公有属性都继承到了子类原型上即成为了子类的公有属性
核心:原型继承并不是把父类中的属性和方法克隆一份,而是让子类和父类增加了原型连接。

相关文章

  • 廖雪峰JS小记

    (function(){})() 原型,原型链 浅谈Js原型的理解JS 原型与原型链终极详解 对象 对象:一种无序...

  • JS原型链模式

    构造函数模式中拥有了类和实例的概念,并且实例和实例之间是相互独立开的即实例识别。基于函数的原型模式解决了方法和属性...

  • JS的__proto__和prototype

    最近在回顾JS的原型和原型链的知识,熟悉JS的同学都知道JS的继承是靠原型链实现的,那跟原型链相关的属性__pro...

  • Javascript(三)之原型继承理解

    进阶路线 3 原型继承 3.1 优秀文章 最详尽的 JS 原型与原型链终极详解 一 最详尽的 JS 原型与原型链终...

  • js集成

    原始继承模式--原型链 2:借用构造函数 3:共享构造原型 4:圣杯模式原型链; 构造函数; 共享原型; 圣杯模式...

  • 从实现角度分析js原型链

    从实现角度分析js原型链 欢迎来我的博客阅读:《从实现角度分析js原型链》 网上介绍原型链的优质文章已经有很多了,...

  • JavaScript中new操作符的详细过程

    理解new对象过程,需要提前了解原型及原型链的相关知识 我们都知道,JS当中创建对象使用的是原型设计模式,即使用n...

  • JS原型链

    1什么是JS原型链? 通过__proto__属性将对象与原型对象进行连接. 1.1 JS原型链的作用? 组成的一个...

  • js 集成模式 07-24

    **原始继承模式--原型链 2:借用构造函数 3:共享构造原型 4:圣杯模式**一:原型链; 二:构造函数; 三:...

  • JavaScript进阶:原型模式

    1、前言 原型模式是指的将原型对象指向创建对象的类,使得不同的类共享原型对象的方法和属性。js中基于原型链的继承的...

网友评论

      本文标题:JS原型链模式

      本文链接:https://www.haomeiwen.com/subject/brynwctx.html