天天看点

创建对象的方式(1)

创建对象的方式(1)

方式一、对象字面量的方式

var student = {

      name : 'lisi',

      age : 18,

      call : function(){

           console.log("我叫"+this.name);

      }

}

上面就创建了一个student对象,但是上面这种方式只适用于创建单个对象。其实很多js插件的开发都用到这种方式对象字面量+原型模式

方式二、工厂模式

functionstudent(name,age){

      var obj = new Object(); //一个空对象

      obj.name = name;  //声明一个name属性

      obj.age = age;

      obj.say = function(){ //声明一个方法

           console.log("我叫"+obj.name);

      }

      return obj;

}

 var student1 = student('lisi',20);

      student1.say();

      console.log(student1 instanceof student);//false

其实这个很好理解,就是把创建对象的过程及结果放到函数里面包装起来。但是用这种方式创建的对象无法被识别类型。就像上面返回false一样,无法判断student1是否是student类型。再拿一个熟悉的例子说:

var arr = newArray();

console.log(arrinstanceof Array); //true

方式三、构造函数模式

functionStudent(name,age){

      this.name = name;

      this.age = age;

      this.say = function(){

           console.log("我叫"+this.name);

      }

}

var student1 = newStudent('lisi',20);

      student1.say();

      console.log(student1 instanceof student);//true

首先函数名称的首字母要大写,主要是为了区别于普通函数。创建对象是在函数外面。这种方式创建的对象类型是能够被识别的。当然上面的构造函数你也可以当作普通函数调用(题外话)

这种方式就没有缺点了吗?答案是否定的。请看下面的例子:

function a(){

      console.log(1);

}

var b = a;

var c = a;

console.log(b===c);//true

我们都知道函数被创建之后,就被分别到内存中。变量b,c只是引用函数的指针,实际上他们调用的函数是一样的。而

var student1 = newStudent('lisi',20);

var student2 = new Student('san',18);

var b = student1.say;

var c = student2.say;

console.log(b===c);//false

有此可知,student1和student2调用的say并不是同一个函数

实际上在调用构造函数时这个方法被重新声明了,显然浪费资源

say :function(){}  等价于 new Function()

所以为了不浪费资源,我们又可以这样

functionStudent(name,age){

      this.name = name;

      this.age = age;

      this.say = say;

}

function say(){

      console.log("我叫"+this.name);

}

var student1 = newStudent('lisi',20);

var student2 = newStudent('san',18);

var b = student1.say;

var c = student2.say;

console.log(b===c);//这时返回的是true

但是这里又有一个问题了,say这个函数是window下全局的函数,并没有制定是哪个对象的,显然会造成一定混乱。因此为了解决这种缺点,js又提供了一种方式原型模式(其实就是对上面几种模式的一种扩充)

继续阅读