创建对象的方式(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又提供了一种方式原型模式(其实就是对上面几种模式的一种扩充)