首页 > 代码库 > JavaScript面向对象与原型(一):构造函数

JavaScript面向对象与原型(一):构造函数

           提到构造函数,我们并不陌生,在面向对象领域,构造函数已经是一个老生常谈的问题了。在JavaScript中再次学习,真的是有一种亲切的感觉。

一、简单回顾           

           构造函数 ,是一种特殊的方法 。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。特别的一个类可以有多个构造函数,可根据其参数个数的不同或参数类型的不同来区分它们即构造函数的重载。


C#构造函数(一个简单的小例子):

<span style="font-size:14px;">public class Cat()
{
	private string name="";
	public Cat()                          //不带参数,如果没有自定义的构造函数,则此为默认
	{
                this.name="无名氏";
	}
	public Cat(string name)   //定义的构造函数,带参数
	{
		this.name=name;
	}
}</span>

           既然都是在创建函数时用到构造函数,那么在JavaScript中怎么创建函数呢?

 

二、JavaScript创建对象

      1、直接使用new创建一个对象,直接看下面代码:

<span style="font-size:14px;">	var box = new Object(); //创建一个 Object 对象
	box.name = 'JavaScript'; //创建一个 name 属性并赋值
	box.runtime = 100; //创建一个 age 属性并赋值
	box.run = function () { //创建一个 run()方法并返回值
	     return this.name + this.runtime + '运行中...';
	};
	alert(box.run()); //输出属性和方法的值</span><span style="font-size: 18px;">
</span>

               这就会出现一个问题,当想创建一个类似的类的时候,就会出现大量的重复代码。为了解决多个类似对象声明的问题,可以使用工厂模式。这里可以回想设计模式中的工厂,就是去解决如何实例化对象的问题。

<span style="font-size:14px;">function createObject(name, age) { //集中实例化的函数
      var obj = new Object();
      obj.name = name;
      obj.age = age;
      obj.run = function () {
           return this.name + this.age + '运行中...';
      };
      return obj;
}
var box1 = createObject('Lee', 100); //第一个实例
var box2 = createObject('Jack', 200); //第二个实例
alert(box1.run());
alert(box2.run()); //保持独立
</span>

二、构造函数上场:

         使用工厂模式,是为了解决实例化对象产生大量重复的问题。但是却无法搞清楚他们到底是哪个对象的实例,也就是识别问题。这就引出了构造函数。

 

             ECMAScript中可以采用构造函数(构造方法)可用来创建特定的对象。类型于 Object 对象。

<span style="font-size:14px;">	function Box(name, age) { //构造函数模式
	     this.name = name;
	     this.age = age;
	     this.run = function () {
	         return this.name + this.age + '运行中...';
	     };
	}
	var box1 = new Box('Lee', 100); //new Box()即可
	var box2 = new Box('Jack', 200);
</span>

构造函数和工厂模式的方法不同之处如下:

1.构造函数方法没有显示的创建对象(newObject());

2.直接将属性和方法赋值给this 对象;

3.没有renturn 语句。

 

构造函数的方法有一些规范:

1.函数名和实例化构造名相同且大写,(PS:非强制,但这么写有助于区分构造函数和普通函数);

2.通过构造函数创建对象,必须使用new 运算符。

 new Object()执行的过程如下:

1.当使用了构造函数,并且new 构造函数(),那么就后台执行了 new Object();

2.将构造函数的作用域给新对象,(即 new Object()创建出的对象), 而函数体内的 this 就

代表new Object()出来的对象。

3.执行构造函数内的代码;

4.返回新对象(后台直接返回)。


(三)判断构造函数内部的方法是基本类型还是引用类型

      使用上面构造函数Box(),做以下比较:

<span style="font-size:14px;">var box1 = new Box('Lee', 100); //传递一致
var box2 = new Box('Lee', 100); //同上
alert(box1.name == box2.name); //true,属性的值相等
alert(box1.run() == box2.run()); //true,方法的值相等,因为传参一致
alert(box1.run == box2.run); //false,方法其实也是一种引用地址</span>

           在实例化box1box2以后他们的地址已经不一样了,虽然run()方法的值是一样的,但是当比较他们的方法的引用地址的时候就返回false了。这就证明了构造函数内部的方法是引用类型的了。

     为了保证引用地址的一致性,可以通过构造函数外面绑定同一个函数的方法。

function Box(name, age) {
      this.name = name;
<pre name="code" class="javascript">      <span style="font-family: 宋体;">this.age = age;</span>
this.run = run;}function run() { //通过外面调用,保证引用地址一致 return this.name + this.age + ‘运行中...‘;}

            虽然使用了全局的函数run()来解决了保证引用地址一致的问题,但这种方式又带来了一个新的问题,全局中的 this在对象调用的时候是 Box 本身,而当作普通函数调用的时候,this 又代表 window。这就带来了this的指向不定的问题。

           

          问题不断的出现,而我们总有办法解决,这就是人类的智慧……请见小编下回分析原型






JavaScript面向对象与原型(一):构造函数