关于 JS 封装等内容


##内容目录
这一周讲课讲了一些关于JS的原理,个人认为很重要,所以想要整理记录下来

[TOC]

1. 封装

Javascript 是非常松散的面向对象语言,它不像其他面向对象语言那样有类的概念,因此,我们需要利用封装把属性和方法联合起来创建一个对象。

  • 最原始的封装的方法是

    以这一种原型:

    1
    2
    3
    4
      var Cat = {
        name : '',
        color : ''
      }

去生成实例对象:

1
2
3
4
5
6
  var cat1 = {}; // 创建一个空对象
    cat1.name = "大毛"; // 按照原型对象的属性赋值
    cat1.color = "黄色";
  var cat2 = {};
    cat2.name = "二毛";
    cat2.color = "黑色";

这一种方法把两个属性封装在一个对象里面,但是这一种方法在应用于需要生成多个实例的时候,写起来会很麻烦,浪费资源,而且实例与原型间也没有联系。

  • 原始模式的改进

    这一种就相当于写一个函数然后去调用它

    1
    2
    3
    4
    5
    6
    7
    8
      function Cat(name,color){
        return {
          name:name,
          color:color
        }
      }
      var cat1 = Cat("大毛","黄色");
      var cat2 = Cat("二毛","黑色");

这一种虽然解决了代码重复的问题,但实例对象间不存在联系。于是又有了另一种模式–>构造函数模式。

  • 构造函数模式

    构造函数,就像构造一个普通的函数,不同的是,它的函数内部利用了 this 关键字,并且在生成实例时用了 new 运算符。

    1
    2
    3
    4
    5
    6
    7
    8
    9
     function Cat(name,color){
        this.name=name;
        this.color=color;
      }//原型对象
      
     var cat1 = new Cat("大毛","黄色");//实例对象
     var cat2 = new Cat("二毛","黑色");//实例对象
     alert(cat1.name); // 大毛
     alert(cat1.color); // 黄色

这一种方法中,cat1 和 cat2 会自动含有一个 constructor 属性,指向它们的构造函数。如果我们用弹窗代码去检验它们是否指向构造函数时,可以看到结果为 true .

1
2
 alert(cat1.constructor == Cat); //true
 alert(cat2.constructor == Cat); //true

我们还可以用 instanceof 运算符去验证实例与原型的关系

1
2
alert(cat1 instanceof Cat); //true
alert(cat2 instanceof Cat); //true

这一种方法可以将实例与原型联系起来,但是它也存在着一个大问题–>浪费内存 !!假如原型函数里面我定义了一个方法或属性,而这个方法或属性是所有的实例对象都共有的,当我生成一个新的实例对象时,这个共有的方法或属性也会被重复生成,这就导致了不必要的内存。
于是乎,就出现了另一种组合函数模型

  • 组合函数模型

这一种方法将原型与函数结合起来:

1
2
3
4
5
6
7
8
9
10
11
12
function Cat(name,color){
    this.name = name;
    this.color = color;
  }

Cat.prototype.type = "猫科动物";
Cat.prototype.eat = function(){alert("吃老鼠")};
  
var cat1 = new Cat("大毛","黄色");//生成实例对象
var cat2 = new Cat("二毛","黑色");//生成实例对象
alert(cat1.type); // 猫科动物
cat1.eat(); // 吃老鼠

这里的type和eat()用的是同一个内存,他们是指向原型对象的,由此节省了内存。

2. 原型链

根据我的理解,当原型既是实例又是原型对象时,原型链可以用这样一个图来表示:

当只有一层关系时,原型链是这样的图:

(内容比较多,内容未完整,资料参考:

http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_encapsulation.html

http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance.html

http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance_continued.html