JavaScript学习总结--创建对象(2)

由于网络原因,所以写了一半就赶紧发了...

书接上回

既然工厂模式创建的对象不属于任何类型,我们知道JavaScript中实际上是没有类(class)这个概念的,所以我们需要创建一个伪类,这就用到了构造函数模式

2.构造函数模式

所谓构造函数,就是将工厂模式改写一下,使用new关键字,模仿JavaScript内置对象的形式来创建对象

我们知道JavaScript的内置对象(Array、Function等),创建时一般是 var aArr=new Array()的写法,且内置对象的首字母为大写,所以构造函数也应该遵循这个规定

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

//创建对象
var person_01=new Person("Sakura",22,"前端开发");

这里可以看到,所谓构造函数实际上也就是一个普通函数,不同的是这个普通函数不能直接在全局作用域下调用,它仅仅用来创建对象

构造函数与工厂模式的区别也很明显

1.构造函数内部并没有显式的使用new Object创建对象,而是在使用new关键字调用时,函数内部自动初始化了一个对象

var obj=new Object

2.紧接着把构造函数的作用域赋值给了这个隐式的新对象(所以构造函数内部的this也不指向构造函数本身,而是指向了调用构造函数后的person_01对象)

3.然后执行构造函数中的代码,为这个新对象创建属性

4.最后隐式的返回出了新对象

前面说到,构造函数本质上是模仿JavaScript的内置对象,所以首字母大写以及new关键字调用就很好的区分了构造函数与普通函数的区别

而此时再回到最初的问题,instanceof能告诉我们什么?

console.log(person_01 instanceof Object);    //true    
console.log(person_01 instanceof Person);    //true

这个时候再用instanceof判断可以得知,新创建的person_01是Person类型的Object

使用构造函数创建对象,假如项目中有多个构造函数以及多个由不同构造函数实例化的对象,那么此时不同构造函数实例化的对象就从属于不同的构造函数

紧接着我们又有了新的问题

假如上面的Person构造函数实例化出了很多个对象,它们有不同的属性,但是它们又有一个相同的sayName方法

var person_01=new Person("Sakura",22,"前端开发");
var person_02=new Person("Misaka",18,"网页设计");
//两个对象拥有一个完全相同的方法sayName
console.log(person_01.sayName==person_02.sayName);//false

为什么会这样呢?

因为当我们用构造函数实例化对象时,实际上是把构造函数内部的sayName方法完完全全复制给了新对象,此时每个对象中的sayName方法都独占一块内存空间,也就是说它们并不是同一个引用,这样在很大程度上又浪费了内存空间,降低了性能,所以我们应该想到,将这个完全相同的方法给每个对象共享,使它们都指向同一个sayName,而不是独自拥有

这里就引入了JavaScript最重要的一个机制,原型

待续...

posted @ 2016-06-01 21:06  Sakura_大表哥  阅读(179)  评论(0编辑  收藏  举报