一.javascript中一般将属性"property)和"方法"method),封装成一个对象。有以下几种方法:

  (1)工厂模式:使用简单的函数创建对象,为对象添加属性和方法,然后返回对象。即就是用函数来封装以特定接口创建对象的细节。

 function CreatePerson(name,age,job){
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function(){
       alert(this.name);
    };
    return o;
}
var per1 = CreatePerson("xiyin",29,"FE");
var per2 = CreatePerson("xixi",21,"UI");

这种模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题。

(2)构造函数模式:可以创建自定义引用类型,可以创建内置对象实例一样使用new操作符。

 function CreatePerson(name,age,job){
     this.name = name;
     this.age = age;
     this.job = job;
     this.getName = function(){
     alert(this.name);
   };
 
 }
 var per1 = new CreatePerson("xixi",22,"SE");
 var per2 = new CreatePerson("xiyin",23,"FF");

per1per2分别保存着 CreatePerson的一个不同实例,这两个对象都有一个constructor属性,该属性指向CreatePerson。也可以使用instanceof操作符来验证是否是对象的实例。

     alert(per1.constructor == CreatePerson);//true
     alert(per2.constructor == CreatePerson);//true
     alert(per1 instanceof Object);//true
     alert(per1 instanceof CreatePerson);//true

构造函数的问题:构造函数的缺点,每个成员都无法得到复用,包括函数.

  属性和方法都是一模一样的内容,每一次生成一个实例,每个方法都要在每个实例上重新创建一遍,不同实例都有构造函数中的方法,但不同实例中的方法不是同一个Function的实例,意味着不同实例上的同名函数是不等,alert(per1.getName == per2.getName);//false;,然而,创建两个完成同样任务的Function实例没有必要,多占用一些内存。这样既不环保,也缺乏效率。

wKioL1dDpbzRmqiLAADhAPBu_Lk836.jpg

   改进让属性和方法在内存中只生成一次,然后所有实例都指向那个内存地址,就是用原型模式:

  (3)原型模式:使用构造函数的prototype属性来指定那些应该共享的属性和方法。

//原型模式
		 function CreatePerson(){}
		 CreatePerson.prototype.name = "xiyin";
		 CreatePerson.prototype.age = "24";
		 CreatePerson.prototype.job = "FE";
		 CreatePerson.prototype.getName = function(){
		 	alert(this.name);
		 }
		 var per1 = new CreatePerson();
		 var per2 = new CreatePerson();
		 per1.getName();//xiyin
		 alert(per1.name==per2.name);//true

wKioL1dDpcjymuPqAADc96ff2d0615.jpg

  (4) 组合原型模式与构造函数模式:组合使用构造函数模式和原型模式时,使用构造函数定义实例属性,而使用原型定义共享的属性和方法。

   Javascript规定,每一个构造函数都有一个prototype属性,指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承。

 function CreatePerson(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
 }
   CreatePerson.prototype.getName = function() {
     alert(this.name);
     };
  var per1 = new CreatePerson("xixi",22,"SE");
  var per2 = new CreatePerson("xiyin",23,"FF");
  alert(per1.getName == per2.getName);//true;

这时所有实例的getName()方法,其实都是同一个内存地址,指向prototype对象,因此就提高了运行效率。

  二. proyotype是每个function定义时自带的属性,并不是所有对象都拥有这个属性.

  function CreatePerson(name,age,job){
     this.name = name;
     this.age = age;
     this.job = job;
   }
     CreatePerson.prototype.firstname = "xi";
     CreatePerson.prototype.getName = function() {
     alert(this.name);
      };
 var per1 = new CreatePerson("xixi",22,"SE"); 
 var per2 = new CreatePerson("xiyin",23,"FF");
  alert(per1 instanceof CreatePerson);//true
  alert(per1.getName == per2.getName);//true;

Prototype相关的方法:

      (1isPrototypeOf()    

   Object.isPrototypeOf( ),一个对象是否是另一个对象的原型。用于判断一个原型对象与实例之间的关系

   语法:object.isPrototypeOf(o);

   参数:o 任意对象

   返回值:如果objecto的原型,则返回true,否则返回false.

       alert(CreatePerson.prototype.isPrototypeOf(per1));//true 

  (2Object.hasOwnProperty( ):检查属性是否被继承。提供了区分继承属性和非继承的局部属性的方法

     使用方法:object.hasOwnProperty( propname);

 参数:一个字符串,包含对象的属性名,

返回值,如objectpropname指定的非继承属性,则返回true,如果object如果没有名为propname指定的属性,或者它从原型对象继承了这个属性,则返回false;  

         alert(per1.hasOwnProperty("name"));//true,nameper1自有的属性

         alert(per1.hasOwnProperty("firstname"));//falsefirstname是继承自prototype对象的属性。

3In运算符:检测某个属性是否存在某个对象中,不管是自有的属性,还是继承的属性。

    用法:左侧是属性名(字符串),右侧是对象,

     返回值:如果对象的自有属性或继承属性中包含这个属性,则返回true

         alert("name" in per1);//true

         alert("firstname" in per1);//true

 (4Object.constructor,对象的构造函数,对象的constructor属性引用了该对象的构造函数。

 (5instanceof 运算符,检测对象在它的原型链中是否有构造函数的原型属性。

      用法:object instanceof constructor

            Object  The object to test.

            ConstructorFunction to test against

        // defining constructors

        function C(){}

        function D(){}

        var o = new C();

        // true, because: Object.getPrototypeOf(o) === C.prototype

        o instanceof C;

        // false, because D.prototype is nowhere in o's prototype chain

        o instanceof D;

        o instanceof Object; // true, because:

        C.prototype instanceof Object // true

三.构造函数,原型,实例的关系

每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象内部的指针。原型提供了一群同类对象共享属性和方法的机制。 

Proyotype是每个function定义时自带的属性,并不是所有对象都拥有这个属性。

Js中的所有对象( undefined null 等特殊情况除外)都有一个内置的 `Prototype` 属性,指向它“父类”的 prototype ,根据 ECMAScript 标准,someObject.`Prototype` 符号是用于指派 someObject 的原型。这个等同于 JavaScript __proto__  属性(现已弃用),但是许多Js的实现(如Node、大部分浏览器等)都提供了一个 __proto__ 属性来指代这一 `Prototype` 。

Javascript 主要通过原型链实现继承。原型链的构建是通过将一个类型的实例赋值给另一个构造函数的原型实现的。