JavaScript 高级程序设计(第3版)笔记——chapter6:面向对象的程序设计

一.创建对象

  • 工厂模式。使用简单的函数创建对象,为对象添加属性和方法,然后返回对象。【问题:没有解决对象识别问题】
  •  1 function createPerson(name, age) {
     2     var o = new Object();
     3     o.name = name;
     4     o.age = age;
     5     o.sayName = function() {
     6         console.log(this.name);
     7     }
     8     return o;
     9 }
    10 
    11 var p1 = createPerson("p1", "10");
    12 p1.sayName(); //p1
    13 console.log(p1 instanceof Object); //true
    14 console.log(p1 instanceof createPerson); //false
  • 构造函数模式。可以创建自定义引用类型,可以像创建内置对象实例一样使用new操作符。缺点:每个成员都无法得到复用。
  •  1 function Person(name, age) {
     2     this.name = name;
     3     this.age = age;
     4     this.sayName = function() {
     5         console.log(this.name);
     6     }
     7 }
     8 var p2 = new Person("p2", 11);
     9 p2.sayName(); //p2
    10 console.log(p2 instanceof Object); //true
    11 console.log(p2 instanceof Person); //true
  • 原型模式。使用构造函数的prototype属性来指定那些应该共享的属性和方法。
  •  1 function person(name) {
     2 }
     3 person.prototype.name = "person";
     4 person.prototype.sayName = function() {
     5     console.log(this.name);
     6 }
     7 var p3 = new person();
     8 var p4 = new person();
     9 p3.sayName();//person
    10 console.log(p3.sayName == p4.sayName);//true
  • 组合使用构造函数模式和原型模式。使用构造函数定义实例属性,而使用原型定义共享的属性和方法。
  •  1 function p(name) {
     2     this.name = name;
     3 }
     4 p.prototype.sayName = function() {
     5     console.log(this.name);
     6 }
     7 var p5 = new p("p5");
     8 var p6 = new p("p6");
     9 p5.sayName();//p5
    10 p6.sayName(); //p6
    11 console.log(p5 instanceof Object); //true
    12 console.log(p5 instanceof p); //true
    13 console.log(p5.constructor instanceof Function);//true

二.继承

  •  通过原型链继承。
  • 注意点1:使用字面量添加新方法会重写原型链。
 1 function SuperType() {
 2     this.property = true;
 3 }
 4 
 5 SuperType.prototype.getSuperValue = function() {
 6     return this.property;
 7 }
 8 
 9 function SubType() {
10     this.subproperty = false;
11 }
12 
13 //继承了SuperType
14 SubType.prototype = new SuperType();
15 
16 //使用字面量添加新方法,会导致上一行代码无效。因为这样重写了原型链
17 SubType.prototype = {
18     getSubValue : function() {
19         return this.property;
20     },
21 
22     someOtherMethod : function() {
23         return false;
24     }
25 };
26 
27 var instance = new SubType();
28 console.log(instance.getSuperValue()); //error
  • 注意点二:包含引用类型值的原型属性会被所有实例共享。
  •  1 function SuperType() {
     2     this.colors = [1,2,3];
     3 }
     4 
     5 function SubType() {
     6 }
     7 
     8 SubType.prototype =  new SuperType();
     9 var instance1 = new SubType();
    10 instance1.colors.push(4);
    11 console.log(instance1.colors); //[ 1, 2, 3, 4 ]
    12 
    13 var instance2 = new SubType();
    14 console.log(instance2.colors); //[ 1, 2, 3, 4 ]
  • 借用构造函数。在子类型构造函数的内部调用超类型构造函数。
  •  1 function SuperType() {
     2     this.colors = [1,2,3];
     3 }
     4 
     5 function SubType() {
     6     SuperType.call(this);
     7 }
     8 
     9 SubType.prototype =  new SuperType();
    10 var instance1 = new SubType();
    11 instance1.colors.push(4);
    12 console.log(instance1.colors); //[ 1, 2, 3, 4 ]
    13 
    14 var instance2 = new SubType();
    15 console.log(instance2.colors); //[ 1, 2, 3]
    /*在新的SubType对象上执行SuperType()函数中定义的所有对象初始化代码。所以,SubType的每个实例就会具有自己的colors属性的副本了。*/
  • 组合继承。使用原型链实现对原型属性和方法的继承。而通过借用构造函数来实现对实例属性的继承。这样,即通过在原型上定义方法实现了函数复用,又能够保证每个实例都有它自己的属性。
  •  1 function Super(name) {
     2     this.name = name;
     3     this.num = [1,2,3];
     4 }
     5 
     6 Super.prototype.SayName = function() {
     7     console.log(this.name);
     8 };
     9 
    10 function sub(name, age) {
    11     //继承属性
    12     Super.call(this, name);
    13     this.age = age;
    14 }
    15 //继承方法
    16 sub.prototype = new Super();
    17 sub.prototype.constructor = sub;
    18 sub.prototype.SayAge = function() {
    19     console.log(this.age);
    20 }
    21 
    22 var i1 = new sub("i1", 29);
    23 i1.num.push(4);
    24 console.log(i1.num);//[ 1, 2, 3, 4 ]
    25 i1.SayAge(); //29
    26 i1.SayName(); //i1
    27 
    28 var i2 = new sub("i2", 27);
    29 console.log(i2.num); //[ 1, 2, 3]
    30 i2.SayAge(); //27
    31 i2.SayName(); //i2
原文地址:https://www.cnblogs.com/HiuYanChong/p/5313831.html