创建对象

我们开始可以用Object构造函数或者对象字面量来快速创建对象,但使用这种方式创建多个对象时会产生大量重复代码,所以我们有了以下几种创建对象的方式。

(1)工厂模式

function createPerson(name, age,sex){ //传入的参数可以类比成送入工厂的原材料
var o = new Object();
o.name = name;
o.age = age;
o.sex = sex;
     o.sayName(){
       alert(this.name);  
     }

    return o; //返回出的对象可以类比成工厂加工完成的产品
}
var person1 = createPerson("Jack",18,"男");
var person2 = createPerson("Rose",18,"女");

当我们使用工厂模式的函数时,并不知道自己所创建的是哪一类对象,也就是说对象之间的辨识度太低,在这基础上我们有了构造函数模式。

(2)构造函数模式

function Person(name, age,sex){
this.name = name; //这里的this在创建对象时会指向新创建的对象
this.age = age;
this.sex = sex;
this.sayName = function{
alert(this.name);
}
}
var person1 = new Person("Jack",18,"男");
var person2 = new Person("Rose",18,"女");

构造函数名可以作为对象的标识符,这样对象的辨识度便上升了。

因为在定义函数时会创建新的Function实例,每一个对象实例的同名方法不是同一个Function实例,每创建一个实例会新创建一个Function实例,这无疑会增加不必要的开销。针对这一点,

我们可以把函数定义在对象外部。

function Person(name, age,sex){
this.name = name;
this.age = age;
this.sex = sex;
this.sayName = sayName;
}
function sayName(){
alert(this.name);
}
var person1 = new Person("Jack",18,"男");
var person2 = new Person("Rose",18,"女");

但是当对象有许多方法需要定义时,我们又会发现需要在全局范围定义许多全局方法,我们就离封装代码的目的越走越远了,所以我们又有了原型模式。

(3)原型模式

function Person(){
}
Person.prototype.name = "Jack";
Person.prototype.age = 18;
Person.prototype.sex = "男";
Person.prototype.sayName = function(){
alert(this.name);
}
var person1 = new Person();
person1.sayName();//"Jack" 开始搜索实例的内部是否有该方法,没有的场合会开始搜索实例的原型对象
var person2 = new Person();
person2.sayName();//"Jack"
alert(person1.sayName == person2.sayName);//true

因为prototype出现了很多次我们也可以这样写

function Person(){
}
Person.prototype = {
     constructor:Person, //这里的constructor属性会变成可枚举的,默认情况下是不枚举的,可以用Object.defineProperty()
name:"Jack",
age:18,
sex:"男",
sayName:function(){
alert(this.name);
}
}

原型模式对于对象函数的共享非常友好,但因为每个对象的所有属性和方法都是公开的,当修改某个实例的属性时,其他实例的属性也会跟着一起改变,换句话说,实例彼此之间的相关性太大,所以我们可以组合使用构造函数模式和原型模式。用构造函数模式来定义实例属性,用原型模式来定义方法和共享的属性。

(4) 构造函数和原型模式组合使用

function Person(name, age,sex){
this.name = name;
this.age = age;
this.sex = sex;
this.friend = ["Jack","Rose"];
}
Person.prototype = {
constructor : Person,
sayName : function(){
alert(this.name);
}
}

当我们想把构造函数和原型写在一起时,可以使用动态原型模式。

(5)动态原型模式

function Person(name, age,sex){
this.name = name;
this.age = age;
this.sex = sex;
if(typeof this.sayName != 'function'){ //通过这种写法,我们不会重复定义函数
Person.prototype.sayName = function(){
alert(this.name);
};
}
}

(6)寄生构造函数模式

function Person(name, age,sex){
var o = new Object(); //在典型构造函数模式中是直接把属性保存在this,这里新创建了一个对象
o.name = name;
o.age = age;
o.sex = sex;
o.sayName = function(){
alert(this.name);
}
return o; //这里和工厂模式又有相似之处,区别在于实例的创建
} var person = new Person("Jack",18,"男"); //表面上是构造的Person对象,实际上是创建的Object类型的对象实例。
person.sayName();//"Jack"

寄生构造函数模式可以创建某个对象的加强版对象

function specialArray(){
var values = new Array();
values.push.apply(values,arguments)//将传来的参数装进数组
values.toPipedString = function(){
values.join('|');
}
return values
}
var cities = new specialArray("Shanghai","Beijing","Guangzhou");
alert(cities.toPipedString());//"Shanghai|Beijing|Guangzhou"

(7)稳妥构造函数模式

稳妥对象指的是没有共有属性,并且方法中不出现this的对象

function Person(name, age,sex){
var o = new Object();
o.sayName = function(){ //只能通过此方法改变属性值
return name;
}
return o;
}

最新文章

  1. #include <vector>用法之我见
  2. LeetCode:Maximum Depth of Binary Tree_104
  3. Kotlin:Android世界的Swift
  4. Codeforces 749C:Voting(暴力模拟)
  5. Hue协作框架
  6. (转)[转]大数据时代的 9 大Key-Value存储数据库
  7. C# 导出 Excel
  8. thinkphp基础入门(1)
  9. C++对象模型2--指针cout结果
  10. Vue.js组件之同级之间的通信
  11. InnoDB online DDL与快速索引创建
  12. Windows下JNI的使用教程
  13. 《剑指offer》数组中出现次数超过数组长度一半的数字
  14. tp5问题整理
  15. maven的安装与配置(本地仓库、阿里云镜像设置)
  16. Java程序设计的第一次作业1
  17. [NLP]非终结字符集&终结字符集
  18. 序列化还是JSON存储对象?
  19. 用git如何把单个文件回退到某一版本
  20. EasyUI表格DataGrid格式化formatter用法

热门文章

  1. javaweb-LoginDemo在JdbcTemp的登录实现及总结+进阶javabean改进
  2. P18_Day2.学习目标
  3. ubuntu16.04安装官方cartographer
  4. NetCore使用ZipFile 和ZipOutputStream
  5. jquery(四:jquery的事件、Ajax)
  6. vue3.0+echart可视化
  7. 分布式共识算法随笔 —— 从 Quorum 到 Paxos
  8. UI自动化中上传与唤醒弹窗
  9. JZOJ 1090. 【SDOI2009】晨跑
  10. 大规模 IoT 边缘容器集群管理的几种架构-5-总结