1.通过Object构造函数或对象字面量创建单个对象
Var obj=new Object(); //在外部生成
Var person={name:’aa’,age:12};
缺点:使用同一个接口创建很多对象,会产生大量的重复代码
2.工厂模式:在一个函数内创建好对象,然后把函数返回 //在内部生成
function creatObj(name, age) {
var obj = new Object;
obj.name = name;
obj.age = age;
obj.study = function() {
alert(this.name);
}
return obj;//返回这个对象的引用}
var stu3 = creatObj("zhangsan",12);//接收这个对象的引用
var stu4 = creatObj("lisi",22);
alert(stu3.name);
stu3.study();
与系统对象的区别:
var arr=new Array();//生成一个系统数组对象
1、系统对象是直接用 new 在外面生成,而工厂定义的是在函数内部生成
2、工厂定义的函数名称第一个是小写开头,而系统定义的是大写开头
好处:解决实例化对象产生大量重复的问题
缺点:工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题,即怎么知道一个对象的类型。
3.构造函数模式
function Student(name, age) {
this.name = name;//后台创建了new Object()
this.age = age;//this就指向了这个对象
this.study = function() {
alert(this.name);
};//后台返回了该对象,没有使用return}
var stu1 = new Student("zhangsan", 12);
alert(stu1.name);
alert(stu1.age);
atu1.study();
使用构造函数方法和使用工厂模式的方法的不同之处:
1.构造函数方法没有显示的创建对象(new Object());
2.直接将属性和方法赋值给this对象
3构造函数没有return语句
//要创建新实例,必须使用new操作符;(否则属性和方法将会被添加到window对象)
构造函数的特点:
1.函数名首字母要大写,为了和普通函数区分
2.使用构造函数必须使用new
//把构造函数当做普通函数调用时没意义
Student(“zhangsan”,12);//没意义
使用insanceof()可以判断具体是什么类型的实例
alert(stu1 instanceof Student);
alert(stu1.study==stu2.study);//false study存储的是函数的引用(存放的是不同的地址)。
构造函数模式的优缺点:
优点:创建自定义函数意味着将来可以将它的实例标识为一种特定的类型,这是构造函数胜过工厂模式的地方
缺点:构造函数内部的方法会被重复创建,不同实例内的同名函数是不相等的。可通过将方法移到构造函数外部解决这一问题,但面临新问题:封装性不好。
4.原型模式:特有的就不能定义在原型中,共有属性定义在原型中
//可以通过isPrototypeOf()方法来确定对象之间是否存在这种关系
function Student() {}
Student.prototype = {
name: "aa",
age: 12,
family: ["爸爸", "妈妈", "妹妹"], //引用类型
fun: function() {
return this.name + this.age + this.family;
}};
var stu1 = new Student();
stu1.name = "bb";
alert(stu1.name); //bb对于基本类型的变量,可以直接修改
stu1.family.push("姐姐");
alert(stu1.family); //爸爸,妈妈,妹妹,姐姐
var stu2 = new Student();
alert(stu2.name); //aa不受影响
alert(stu2.family);//受影响 爸爸,妈妈,妹妹,姐姐
//引用类型,用的是同一个,基本类型用的是各自的
好处:可以让所有对象实例共享它所包含的属性和方法。
缺点:原型中是所有属性都是共享的,但是实例一般都是要有自己的单独属性的
5.组合使用构造函数模式和原型模式:构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性。所以每个实例都会有自己的一份实例属性的副本,但同时共享着对方法的引用,最大限度的节省了内存,同时支持向构造函数传递参数。
function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.friends=["S","C"];}
Person.prototype={
constructor:Person,
sayName:function(){
alert(this.name);
}};
var person1=new Person(...);
6.动态原型模式
function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
if(typeof this.sayName!="function"){
Person.prototype.sayName=function(){
alert(this.name);
};
}}
这里只有sayName()不存在的情况下,才会将它添加到原型中,这段代码只会在初次调用构造函数时才执行。这里对原型所做的修改,能够立刻在所有实例中得到反映。
7.Object.create()
ES5定义了一个名为Object.create()的方法,它创建一个新对象,其中第一个参数是这个对象的原型,第二个参数对对象的属性进行进一步描述。
8.寄生构造函数模式和稳妥构造函数模式
寄生构造函数:工厂模式+构造函数—>不建议使用
不能实现类似于原型的数据共享
function Student(name, age) {
var obj = new Object();
obj.name = name;
obj.age = age;
obj.fun = function() {
return this.name + this.age;};
return obj;}
var stu = new Student("zhang", 12);
alert(stu.fun());
稳妥构造函数:在一些安全的环境中,比如禁止使用this和new,这里的this是构造函数不适用this,这里的new是在外部实例化构造函数时不使用new
function Person(name,age){
var obj = new Object();
obj.fun=function(){
return name+age;//直接使用参数的值}
return obj;}
var person = Person("zhang",12);//不能使用new创建对象
alert(person.fun());
//给JS内部的引用类型的原型对象添加方法,但是不建议这样使用,因为容易发生命名冲突
alert(String.prototype.substr); //function substr() { [native code] }
String.prototype.myStr = function() {
return this + "是个字符串";}
var ss = "hello";
alert(ss.myStr());//hello是个字符串*/