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最重要的一个机制,原型
待续...