js设计模式--创建型--原型模式

  创建型:原型模式

  原型模式不仅是一种设计模式,还是一种编程规范,是js面向对象系统实现的根基。

  在原型模式下,要创建一个对象时,会先找到一个对象作为原型,然后通过 克隆原型 的方式来创建一个与原型一样的对象。

  JS中的类,本质上是 原型继承的语法糖。

ECMAScript 2015 中引入的 JavaScript 类实质上是 JavaScript 现有的基于原型的继承的语法糖。

类语法不会为 JavaScript 引入新的面向对象的继承模型。 ——MDN

class Dog{
    constructor(name,age){
        this.name = name;
        this.age = age;
    }
    eat(){
        console.log("我是吃吃吃")
    }
}
// 完全就等价于下面这个构造函数
function Dog1(name,age){
    this.name = name;
    this.age = age;
}
Dog.prototype.eat = function(){
    console.log("我是吃吃吃1")
}

  所以说JS语言本身就是原型模式。JS本身类型就比较模糊,不存在类型耦合的问题,所以没必要强行把原型模式当作设计模式去理解,它作为一种编程规范来讨论更合适。

  原型编程规范的核心思想就是 利用实例来描述对象,用实例作为定义对象和继承的基础。

  在JS中,原型编程规范的体现就是基于原型链的继承

  原型

  在JS中,每一个构造函数都有一个 prototype 属性,它指向构造函数的原型对象,这个原型对象中有一个 constructor 属性指回构造函数,每一个实例都有一个

__proto__属性,当使用构造函数创建实例时,实例的 __proto__ 属性就会指向构造函数的原型对象。

// 创建一个Dog构造函数
function Dog(name, age) {
  this.name = name
  this.age = age
}
Dog.prototype.eat = function() {
  console.log('吃吃吃')
}
// 使用Dog构造函数创建dog实例
const dog = new Dog('旺财', 4)

  上面这段代码几个实体之间存在的关系

  

  原型链

// 调用上面的方法
dog.eat()
// 输出"吃吃吃"
dog.toString()
// 输出"[object Object]"

  在 dog 实例中明明没有手动定义,eat和toString 方法,但是还是可以调用成功。这是因为当我们试图访问一个 JS 实例的属性/方法时,首先搜索实例本身,如果实例没有定义对应的属性/方法时,它会转而去搜索实例的原型对象;如果原型对象也没有找到,他就去搜索原型对象的原型对象,这个搜索轨迹,就是原型链。

  eat方法和toString方法的调用过程为例,它的搜索过程如下图:

  

  上图彼此相连的 prototype,就组成一个原型链。

  几乎所有的JS中的对象都是位于原型链顶端的Object 的实例,除了object.prototype

原文地址:https://www.cnblogs.com/Sabo-dudu/p/14649262.html