引言

 

除JSON外,在JavaScript中我们可以使用new操作符结合一个函数的形式来创建对象。例如:

    function MyFunc() {};         //定义一个空函数

    var anObj = new MyFunc();  //使用 new 操作符,借助 MyFun 函数,就创建了一个对象

 

JavaScript的这种创建对象的方式可真有意思,如何去理解这种写法呢?其实,可以把上面的代码改写成这种等价形式:

    function MyFunc(){};

    var anObj = {};     //创建一个对象

    MyFunc.call(anObj); //将 anObj对象作为 this 指针调用MyFunc函数

 

new操作符就可以分解为,执行引擎先创建一个对象,然后再将这个对象传递给函数,作为函数的this,并执行改函数。

 

构造函数

 

      看到此处有人也许会想,为什么不不把上面的MyFunc函数作为anobj对象的构造函数?呵呵,如果你想到了就太聪明了,因为JavaScript也是这么想的并且就是这么做的,看下面的代码:

 

<script language="javascript">
function person(name){ //构造函数person
this.name = name;
this.say = function(){alert("hello, i'm " + this.name);}
}

function employee(name, salary){ //构造函数employee
//将employee对象传递给person的this并调用person函数,所以person就相当于employee对象的构造函数了
person.call(this, name);
this.salary = salary;
this.showMoney = function(){alert("my salary is " + this.salary);}
}

var bill = new person("BillGates");
var jek = new employee("jekbaor", 5000);
bill.say();
jek.say();
jek.showMoney();

alert(bill.constructor == person); //true,表明bill对象使用person函数构造
alert(jek.constructor == employee); //true,表明jek对象使用employee函数构造
alert(bill.say == jek.say); //false
</script>

这段代码表明,函数不但可以当作构造函数,而且还可以带参数,还可以为对象添加成员和方法。其中的person.call(this, name);,Employee构造函数又将自己接收的this作为参数调用Person构造函数,这就是相当于调用基类的构造函数。alert(bill.constructor == person);和alert(jek.constructor == employee);还表明这样一个意思:BillGates 是由 Person 构造的,而 SteveJobs 是由Employee 构造的。对象内置的constructor属性还指明了构造对象所用的具体函数!

 

但要注意的是,用构造函数操作 this 对象创建出来的每一个对象,不但具有各自的成员数据,而且还具有各自的方法数据。换句话说,方法的代码体(体现函数逻辑的数据)在每一个对象中都存在一个副本。

同一类的对象各自有一份方法代码显然是一种浪费。在传统的对象语言中,方法函数并不象 JavaScript那样是个对象概念。即使也有象函数指针、方法指针或委托那样的变化形式,但其实质也是对同一份代码的引用。一般的对象语言很难遇到这种情况。

 

      要解决这个问题就要看下面说的prototype属性。