原型设计模式和设计规则

50 阅读3分钟

原型规则

  1. 原型规则
  • 所有的引用类型(数组、对象、函数)都具有对象特征,即可以拓展属性(除了);
let arr = []; arr.a = 1;
  • 所有的引用类型,都有一个_proto_属性(隐式原型),属性值是一个普通对象;
let obj = {};
obj.a = 100;
let arr = [];
arr.a = 100;
function fn() {

}
fn.a = 100;
console.log(obj._proto_);
console.log(arr._proto_);
console.log(fn._proto_);
// 执行结果
// undefined
// undefined
// undefined
  • 所有函数,都有一个prototype(显式原型),属性值也是一个普通原型;
console.log(fn.prototype);  // {}
  • 所有的引用类型(数组、对象、函数),其隐式原型指向其构造函数的显式原型;
obj._proto_ === Object.prototype
  • 当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去它的_proto_(即它的构造函数的prototype)中去寻找
// 构造函数
function Fn(name) {
  this.name = name;
}

// 显示原型
Fn.prototype.alertName = function() {
  console.log(this.name);
}

// 创建实例
let f = new Fn('张三');
f.printName = function() {
  console.log(this.name);
}

f.printName();  // 张三
f.alertName();  // 张三
  1. 原型对象
    prototype在js中,函数对象其中一个属性:原型对象prototype。普通对象没有prototype属性,但有_proto_属性。原型的作用就是给这个类的每一个对象都添加一个统一的方法,在原型中定义的方法和属性都是被所有实例对象所共享。
let person = function(name) {
    this.name = name;
};
person.prototype.getName = function() {
    // 通过person.prototype设置函数对象属性
    return this.name;
}
let crazy = new person('crazyLee');
crazy.getName();  // crazyLee
  1. 原型链
    当试图得到一个对象f的某个属性时,如果这个对象本身没有这个属性,那么会去它的_proto_(即它的构造函数的prototype)obj._proto_中去寻找;当obj._proto_也没有时,便会在obj.proto.proto(即obj的构造函数的prototype的构造函数的prototype)中寻找。

设计模式

  1. 工厂模式
    在函数内创建一个对象,给对象赋予属性及方法再将对象返回
function Person() {
  let People = new Object();
  People.name = 'CrazyLee';
  People.age = '25';
  People.sex = function() {
    return 'boy';
  }
  return People;
}
let a = Person();
console.log(a.name);
console.log(a.sex());
a.weight = '85kg';
console.log(a.weight);
a.name = 'June';
console.log(a.name);
let b = Person();
console.log(b.name);
console.log(b.weight);
// 执行结果:
// CrazyLee
// boy
// 85kg
// June
// CrazyLee
// undefined
  1. 构造函数模式
    无需在函数内部重新创建对象,而是用this指代
function Person() {
  this.name = 'CrazyLee';
  this.age = '25';
  this.sex = function() {
    return 'boy';
  }
}
let a = new Person();
console.log(a.name);
console.log(a.sex());
a.weight = '85kg';
console.log(a.weight);
a.name = 'June';
console.log(a.name);
let b = new Person();
console.log(b.name);
console.log(b.weight);
// 执行结果:
// CrazyLee
// boy
// 85kg
// June
// CrazyLee
// undefined
  1. 原型模式
    函数中不对属性进行定义,利用prototype属性进行定义,可以让所有对象实例共享它所包含的属性和方法。
function Parent() {
  Parent.prototype.name = 'crazy';
  Parent.prototype.age = '24';
  Parent.prototype.sex = function() {
    let s = '女';
    console.log(s);
  }
}
let x = new Parent();
console.log(x.name);
console.log(x.sex());
x.name = 'June';
console.log(x.name);
let y = new Parent();
console.log(y.name);
// 执行结果
// crazy
// 女
// undefined
// June
// crazy
  1. 混合模式
    原型模式+构造函数模式。这种模式中,构造函数模式用于定义实例属性,而原型模式用于定义方法和共享属性。
function Parent() {
  this.name = 'Crazy';
  this.age = 24;
};
Parent.prototype.sayname = function() {
  return this.name;
}
let x = new Parent();
console.log(x.sayname());
// 执行结果:
// Crazy
  1. 动态原型模式
    将所有信息封装在了构造函数中,而通过构造函数中初始化原型,这个可以通过判断该方法是否有效而选择是否需要初始化原型。
function Parent() {
  this.name = 'Crazy';
  this.age = 24;
  if(typeof Parent._sayname == 'undefined') {
    Parent.prototype.sayname = function() {
      return this.name;
    }
    Parent._sayname = true;
  }
};
let x = new Parent();
console.log(x.sayname());
// 执行结果:
// Crazy