浅析创建javascript对象的方法


Posted in Javascript onMay 13, 2016

一、工厂模式

function person (name,age) {
  var p=new Object();
  p.name=name;
  p.age=age;
  p.showMessage=function(){
    console.log("name:"+this.name+" age:"+this.age);
  }
  return p;
}
var p1=person("k1",28);
var p2=person("k2",29);
console.log(p1.showMessage==p2.showMessage);//false 不是同一个showMessage方法
console.log(p1.constructor);//[object] 都是object

工厂模式的缺陷是:没解决对象识别的问题,而且每个对象的showMessage方法都不是同一个方法(每个方法在每个对象实例上都重新创建了一遍),增加了开销

二、构造函数模式

function Person (name,age) {
  this.name=name;
  this.age=age;
  this.showMessage=function(){
    console.log("name:"+this.name+" age:"+this.age);
  }
}
var p1=new Person("k1",28);
var p2=new Person("k2",29);
console.log(p1.showMessage==p2.showMessage);//false 不是同一个showMessage方法
console.log(p1.constructor);//[Person]
console.log(p1 instanceof Person);// true

构造函数模式解决了对象识别的问题,但是每个对象的showMessage方法不是同一个方法(每个方法在每个对象实例上都重新创建了一遍),增加了开销

三、原型模式

function Person () {
  
}
Person.prototype.name ="k";
Person.prototype.age =29;
Person.prototype.showMessage=function () {
  console.log("name:"+this.name+" age:"+this.age);
};

var p1=new Person();
p1.showMessage();//name:k age:29

var p2=new Person();
p2.showMessage();//name:k age:29

console.log(p1.showMessage==p2.showMessage);// true --引用的是同一函数
console.log(p1.constructor)//[Person] --对象识别
console.log(p1 instanceof Person)//true --对象识别
console.log(Person.prototype.isPrototypeOf(p1));// true
console.log(Object.getPrototypeOf(p1)==Person.prototype);// true

原型模式解决了“每个方法在每个对象实例上都重新创建了一遍”的问题,也解决了对象识别的问题

原型模式有个很大的问题是,因为挂载在函数prototype下面的所有对象、变量、函数都是被该函数的所有实例共享的,虽然通过实例p1、p2可以访问到prototype的属性,但是却不能修改属性值,例如p1.name="k1",只是在p1实例上添加了一个name="k1"的属性,并没改到prototype.name。如果是值类型还好,如果是引用类型的话,就会有问题了,看如下的例子

function Person () {  
};
Person.prototype.age =10;
Person.prototype.array=[1,2,3];

var p1=new Person();
var p2=new Person();
console.log(p1.array);// [1,2,3]
console.log(p2.array); //[1,2,3]
p1.array.push(4);
console.log(p1.array);//[1,2,3,4]
console.log(p2.array);//[1,2,3,4]

p1往array里面添加了值,在p2也反映出来了,因为他们都是指向同一个array

四、组合使用构造函数模式和原型模式

这是最常见的创建对象的方式,结合了构造函数和原型模式的优点

function Person (name,age) {
  this.name=name;
  this.age=age;
}

Person.prototype.showMessage = function() {
  console.log("name:"+this.name+" age:"+this.age);
};

var p1=new Person("k",30);
p1.showMessage();

五、动态原型模式

主要是解决:把所有的信息都封装在构造函数中,更符合oo的思想

function Person (name,age) {
  this.name=name;
  this.age=age;
  if(typeof this.showMessage!="function"){
    Person.prototype.showMessage=function(){
      console.log("name:"+this.name+" age:"+this.age);
    }
  }
}

var p1=new Person("k",30);
p1.showMessage();

六、寄生构造函数模式

function Person (name,age) {
  var o=new Object();
  o.name=name;
  o.age=age;
  o.sayName=function(){
    console.log(this.name);
  };
  return o;
}
var p1=new Person("k",28);
p1.sayName();

寄生构造函数模式和工厂模式是一模一样的,只不过创建对象的时候使用了new 关键字,上例:var p1=new Person("k",28)。

它的主要作用是:在这个构造函数里面进行功能的扩展,例如,我想定义一个数组类型MyArray,它是以Array数组为基础的,有一个自己的方法,如下

function MyArray(){
  var values=new Array();
  values.push.apply(values,arguments);
  //自己定义的方法
  values.toPipedString=function(){ 
    return this.join('|');
  };
  return values;
}
var colors=new MyArray("red","blue","green");
console.log(colors.toPipedString());
console.log(colors instanceof Array);

七、稳妥构造函数模式

稳妥构造函数遵循与寄生构造函数类型的模式,但有两点不同:一是不使用this,二是不使用new 调用构造函数

function Person (name,age) {
  var o=new Object();
  var tempAge=age;

  o.name=name;
  o.age=age;

  o.sayName=function(){
    console.log(name);
  }
  o.sayAge=function(){
    console.log(tempAge);
  }
  return o;
}

var p1=Person("k1",28);
p1.sayName(); // k1
p1.sayAge(); // 28

p1.name="k2";
p1.age=30;
p1.sayName(); // k1
p1.sayAge();  //28

看到如上的输出就很好理解什么叫稳妥对象模式了,就是用这种模式创建的对象,没有其他办法能够改变初始化时候传入的值,这里是Person("k1",28),这样的对象就是稳妥对象,实际上这里使用到就是javascript的闭包了。

以上这篇浅析创建javascript对象的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
YUI的Tab切换实现代码
Apr 11 Javascript
Js base64 加密解密介绍
Oct 11 Javascript
javascript拖拽应用实例
Mar 25 Javascript
Vue.js系列之项目结构说明(2)
Jan 03 Javascript
Webpack实现按需打包Lodash的几种方法详解
May 08 Javascript
vue2.0 资源文件assets和static的区别详解
Apr 08 Javascript
微信小程序表单弹窗实例
Jul 19 Javascript
解决vuejs项目里css引用背景图片不能显示的问题
Sep 13 Javascript
小程序日历控件使用方法详解
Dec 29 Javascript
jquery分页优化操作实例分析
Aug 23 jQuery
js实现二级联动简单实例
Jan 11 Javascript
让JavaScript代码更加精简的方法技巧
Jun 01 Javascript
全面理解JavaScript中的闭包
May 12 #Javascript
Bootstrap框架动态生成Web页面文章内目录的方法
May 12 #Javascript
Node.js的项目构建工具Grunt的安装与配置教程
May 12 #Javascript
js自定义select下拉框美化特效
May 12 #Javascript
使用jQuery制作遮罩层弹出效果的极简实例分享
May 12 #Javascript
JS函数的定义与调用方法推荐
May 12 #Javascript
使用jQuery实现Web页面换肤功能的要点解析
May 12 #Javascript
You might like
phpwind中的数据库操作类
2007/01/02 PHP
用C/C++扩展你的PHP 为你的php增加功能
2012/09/06 PHP
YII Framework框架教程之安全方案详解
2016/03/14 PHP
PHPWind9.0手动屏蔽验证码解决后台关闭验证码但是依然显示的问题
2016/08/12 PHP
利用PHP获取网站访客的所在地位置
2017/01/18 PHP
laravel 解决ajax异步提交数据,并还回填充表格的问题
2019/10/15 PHP
Prototype 学习 Prototype对象
2009/07/12 Javascript
php图像生成函数之间的区别分析
2012/12/06 Javascript
Javascript简单改变表单元素背景的方法
2015/07/15 Javascript
JS功能代码集锦
2016/05/04 Javascript
JavaScript 身份证号有效验证详解及实例代码
2016/10/20 Javascript
解析javascript图片懒加载与预加载的分析总结
2016/10/27 Javascript
js实现定时进度条完成后切换图片
2017/01/04 Javascript
对angular 监控数据模型变化的事件方法$watch详解
2018/10/09 Javascript
8个有意思的JavaScript面试题
2019/07/30 Javascript
vue改变循环遍历后的数据实例
2019/11/07 Javascript
基于vue.js实现购物车
2020/01/15 Javascript
js实现飞机大战小游戏
2020/08/26 Javascript
vue实现下载文件流完整前后端代码
2020/11/17 Vue.js
[01:06:54]DOTA2-DPC中国联赛 正赛 SAG vs DLG BO3 第二场 2月28日
2021/03/11 DOTA
布同自制Python函数帮助查询小工具
2011/03/13 Python
Python检查ping终端的方法
2019/01/26 Python
Python3数字求和的实例
2019/02/19 Python
浅谈python标准库--functools.partial
2019/03/13 Python
200行python代码实现贪吃蛇游戏
2020/04/24 Python
Python代码需要缩进吗
2020/07/01 Python
CSS3 filter(滤镜)实现网页灰色或者黑色模式的代码
2020/11/30 HTML / CSS
波兰汽车配件网上商店:iParts.pl
2020/09/08 全球购物
SQL数据库笔试题
2016/03/08 面试题
怎样写好自荐信和推荐信
2013/12/26 职场文书
秋季运动会加油稿200字
2014/01/11 职场文书
会计专业职业规划:规划自我赢取未来
2014/02/12 职场文书
爱护公物标语
2014/06/24 职场文书
优秀大学生自荐信
2015/03/26 职场文书
Redis命令处理过程源码解析
2022/02/12 Redis
Vue elementUI表单嵌套表格并对每行进行校验详解
2022/02/18 Vue.js