建立对象 --- 构造函数模式

ECMAScript中的构造函数能够用来创造特定类型的对象,Object和Array 是原生构造函数,在 运行时会自动出如今执行环境。也能够自定义构造函数,示例以下:函数

function Person(name,age,job){      
            this.name = name;
            this.age = age;
            this.job = job;
            this.sayName = function(){
                  alert(this.name);
            };   
}
var person1 = new Person("wsc",25,"software Engineer");
var person2 = new Person("yl",26,"Doctor");

注意:按照惯例,构造函数始终都应该以一个大写字母开头,而非构造函数则应该以一个小写字母开头,目的是区别ECMAScript中的其余函数,由于构造函数也是函数,只是配用来建立对象;this

(1).建立Person新实例,必须使用new操纵符。这种方式调用构造函数实际上经历一下4个步骤:
  1.建立一个新对象;spa

  2.将构造函数的做用域赋给新对象;code

  3.执行构造函数中的代码;对象

  4.返回新对象;blog

(2).构造函数都有一个构造函数属性constructor,该属性指向该对象所属的实例,之前面的例子为准:继承

  alert(person1.constructor == Person);//trueip

  1.对象的constructor属性主要目的是用来标识对象类型;作用域

  2.检测对象类型主要是用instanceof,示例以下:
    alert(person1 instanceof Object);//true   注意:全部的对象均继承Object
    alert(person1 instanceof Person);//true原型

  3.建立自定义构造函数意味着未来能够将它的实力标识为一种特定的类型,这是构造模式赛过工厂模式的地方,

  注意:以这种方式的构造函数是定义在Global对象中的;

(3).构造函数与其余函数的惟一区别是调用方式的不一样:任何函数只要经过new操做符来调用,那么它就做为构造函数;任何函数若是不经过new操做符来调用,那么它就做为普通函数;

// 看成构造函数
var person = new Person("wsc",26,"Software Engineer");
person.sayName();//"wsc";

//普通函数
Person("wsc",26,"Software Engineer");//添加到window
window.sayName()//"wsc"

//在另外一个对象的做用域中调用
var o = new Object();
Person.call(o,"wsc",26,"Software Engineer");
o.sayName();//"wsc"

 (4).构造函数的问题

  构造函数的主要问题是:每一个方法都要在每一个实例上从新建立一遍。

  以上面的例子为例:从逻辑上,此时的构造函数还能够以下定义。

  

function Person(name,age,job){
      this.name = name;
      this.age = age;
      this.job = job;
      this.sayName = new Function("alert(this.name)");//与声明函数在逻辑上是等价的        
}

//在这里ECMAscript中的函数也是对象;

此种方式建立函数,会致使不一样的做用域链和标识符解析,但在建立Function新实例的机制仍然是相同的。所以不一样实例上同名的函数是不等的。

 

解决此问题的方式以下:

function Person(name,age,job){
      this.name = name;
      this.age = age;
      this.job = job;
      this.sayName = sayName;
}

function sayName(){
    alert(this.name);
}

var person1 = new Person("wsc",29,"software engineer");
var person2 = new Person("wife",26,"techer");
alert(person1.sayName === person2.sayName);//?

但此种方式,又会产生新的问题:全局函数只能被某个对象调用,若是对象须要定义不少方法,这就须要定义多个全局函数。如何解决呢?看原型

相关文章
相关标签/搜索