文章目录
参考:
1. https://www.cnblogs.com/juggdxy/p/8245491.html
2. https://blog.youkuaiyun.com/qq_43495629/article/details/87880635
1.new 操作符 + Object 创建对象
调用系统构造函数创建对象
1 var person = new Object();
2 person.name = "lisi";
3 person.age = 21;
4 person.family = ["lida","lier","wangwu"];
5 person.say = function(){
6 alert(this.name);
7 }
person.say()//this指向调用的person
2.字面式创建对象
直接写属性,方法,逗号隔开
var person ={
name: "lisi",
age: 21,
family: ["lida","lier","wangwu"],
say: function(){
alert(this.name);
}
};
以上两种方法在使用同一接口创建多个对象时,会产生大量重复代码,为了解决此问题,工厂模式被开发。
3.工厂模式
function createPerson(name,age,family) {
var o = new Object();//创建对象
o.name = name;
o.age = age;
o.family = family;//添加属性
o.say = function(){
alert(this.name);
}//添加方法
return o;
}
var person1 = createPerson("lisi",21,["lida","lier","wangwu"]); //instanceof无法判断它是谁的实例,只能判断他是对象,构造函数都可以判断出
var person2 = createPerson("wangwu",18,["lida","lier","lisi"]);
console.log(person1 instanceof Object); //true
工厂模式解决了重复实例化多个对象的问题,但没有解决对象识别的问题(但是工厂模式却无从识别对象的类型,因为全部都是Object,不像Date、Array等,本例中,得到的都是o对象,对象的类型都是Object,因此出现了构造函数模式)。
4.构造函数创建对象
function Person(name,age,family) {
this.name = name;
this.age = age;
this.family = family;
this.say = function(){
alert(this.name);
}
}
var person1 = new Person("lisi",21,["lida","lier","wangwu"]);
var person2 = new Person("lisi",21,["lida","lier","lisi"]);
console.log(person1 instanceof Object); //true
console.log(person1 instanceof Person); //true
console.log(person2 instanceof Object); //true
console.log(person2 instanceof Person); //true
console.log(person1.constructor); //constructor 属性返回创建此对象的构造函数
对比工厂模式有以下不同之处:
1、没有显式地创建对象
2、直接将属性和方法赋给了 this 对象
3、没有 return 语句
5.原型模式
1 function Person() {
2 }
3
4 Person.prototype.name = "lisi";
5 Person.prototype.age = 21;
6 Person.prototype.family = ["lida","lier","wangwu"];
7 Person.prototype.say = function(){
8 alert(this.name);
9 };
10 console.log(Person.prototype); //Object{name: 'lisi', age: 21, family: Array[3]}
11
12 var person1 = new Person(); //创建一个实例person1
13 console.log(person1.name); //lisi
14
15 var person2 = new Person(); //创建实例person2
16 person2.name = "wangwu";
17 person2.family = ["lida","lier","lisi"];
18 console.log(person2); //Person {name: "wangwu", family: Array[3]}
19 // console.log(person2.prototype.name); //报错
20 console.log(person2.age); //21
原型模式的好处是所有对象实例共享它的属性和方法(即所谓的共有属性)
6.混合模式(构造函数模式+原型模式)
构造函数模式用于定义实例属性,原型模式用于定义方法和共享的属性
1 function Person(name,age,family){
2 this.name = name;
3 this.age = age;
4 this.family = family;
5 }
6
7 Person.prototype = {
8 constructor: Person, //每个函数都有prototype属性,指向该函数原型对象,原型对象都有constructor属性,这是一个指向prototype属性所在函数的指针
9 say: function(){
10 alert(this.name);
11 }
12 }
13
14 var person1 = new Person("lisi",21,["lida","lier","wangwu"]);
15 console.log(person1);
16 var person2 = new Person("wangwu",21,["lida","lier","lisi"]);
17 console.log(person2);
混合模式共享着对相同方法的引用,又保证了每个实例有自己的私有属性。最大限度的节省了内存
7.动态原型模式(要new)
动态原型模式将所有的信息都封装在构造函数中(包括原型和实例属性),通过在构造函数中实例化原型(仅在必要的情况下)实现封装,又保持了同时使用构造函数和原型的优点。
function Model(name,age,hobby){
this.name = name;
this.age = age;
this.hobby = hobby;
//方法(如果show()方法不存在,才会动态添加,而且这个方法在初次调用构造函数才会执行,不调用构造函数就不会执行,不然每次实例化一个Model对象都会去写一遍原型对象);
if(typeof this.show != "function"){
Model.prototype.show = function(){
alert(this.name);
}
}
}
var object5 = new Model("YYM",20,"baseball");
object5.show();
alert(object5.constructor); //输出: Model构造函数所对应的方法体
alert(object5 instanceof Model); //输出:true 说明object5是Model对象的实例
可以同时使用constructor和instanceof来检查他们的类型
8.寄生构造函数模式
和工厂模式的唯一区别就是,要使用new来创建对象。
function createModel(name,age,hobby){
var o = {};
o.name = name;
o.age = age;
o.hobby = hobby;
o.show = function(){
alert(this.name);
}; //注意这里的分号;
return o; //返回这个对象;
}
var object1 = new createModel("YYM",20,"baseball");
object1.show(); //"YYM"
———————————
然后分析其与工厂模式的区别:
1、寄生模式创建对象时使用了New关键字
2、寄生模式的外部包装函数是一个构造函数
9.稳妥构造函数模式
不new,不使用this,无公共属性,要访问函数内部的自定义私有属性,只能通过创建对象来调用本函数内部自定义的属性访问方法,来获得私有属性的访问权。
function createModel(name,age,hobby){
var o = {};
//可以自己在这里定义私有属性和函数;
//方法;
o.show = function(){
alert(name); //注意这里不再使用this;
}
return o; //返回这个对象;
}
var object1 = createModel("YYM",20,"baseball"); //不new
object1.show(); //"YYM"