js中创建对象的几种方式示例介绍


Posted in Javascript onJanuary 26, 2014

JavaScript中的所有事物都是对象:字符串、数组、数值、函数等。JS中并没有类的概念,

但我们可以利用JS的语法特征,以类的思想来创建对象。

原始方法

<script type="text/javascript"> var obj = new Object(); 
obj.name = "Koji"; //为对象添加属性 
obj.age = 21; 
obj.showName = function(){ //为对象添加方法 
alert(this.name); 
} 
obj.showAge = function(){ 
alert(this.age); 
} 
obj.showName(); //Koji 
obj.showAge(); //21 
</script>

上面的方式通过new关键字生成一个对象,然后根据JS是动态语言的特性添加属性和方法,构

造一个对象。其中的this是表示调用该方法的对象。

这种方式的问题是如果需要多次创建对象,则需要重复代码多次,不利于代码的复用。

工厂方法

<script type="text/javascript"> function createObj(){ 
var obj = new Object(); //创建对象 
obj.name = "Koji"; 
obj.age = 21; 
obj.showName = function(){ 
alert(this.name); 
} 
obj.showAge = function(){ 
alert(this.age); 
} 
return obj; //返回对象 
} 
var obj1 = createObj(); 
var obj2 = createObj(); 
obj1.showName(); //Koji 
obj2.showAge(); //21 
</script>

这种方式提高了代码重用率,还可以改变工厂方法,传入参数赋值。
<script type="text/javascript"> function createObj(name, age){ //构造对象时可以传入初始化参数 
var obj = new Object(); //创建对象 
obj.name = name; 
obj.age = age; 
obj.showName = function(){ 
alert(this.name); 
} 
obj.showAge = function(){ 
alert(this.age); 
} 
return obj; //返回对象 
} 
var obj1 = createObj("Koji", 22); 
var obj2 = createObj("Luo", 21); 
obj1.showName(); //Koji 
obj1.showAge(); //22 
obj2.showName(); //Luo 
obj2.showAge(); //21 
</script>

上面的方式虽然可以提高代码的复用率,但和面向对象中类的概念相比有一个很大的缺陷。面

相对象强调对象的属性私有,而对象的方法是共享的。而上面的工厂方法创建对象的时候要为每个

对象创建各自私有的方法。同时由于为每个对象都创建逻辑相同的方法,浪费内存。改进如下

<span style="font-size:14px;"><script type="text/javascript"> function createObj(name, age){ 
var obj = new Object(); //创建对象 
obj.name = name; 
obj.age = age; 
obj.showName = showName; 
obj.showAge = showAge; 
return obj; //返回对象 
} 
function showName(){ //函数也是一个对象 
alert(this.name); 
} 
function showAge(){ 
alert(this.age); 
} 
var obj1 = createObj("Koji", 22); 
var obj2 = createObj("Luo", 21); 
obj1.showName(); //Koji 
obj1.showAge(); //22 
obj2.showName(); //Luo 
obj2.showAge(); //21 
</script></span>

上面通过定义连个函数对象,解决了不同对象持有函数对象的私有问题。现在所有对象的方法都

持有上面两个函数的引用。但这么一来的话,对象的函数又和对象成了相互独立,不相干的了。这和

面向对象中特定方法属于特定类的思想不符合。

构造函数方式

<script type="text/javascript"> //定义一个构造函数,用来生成对应的对象,可以类比Java中的构造函数 
function Person(name, age){ 
//当调用new Person的时候,在执行第一行代码前,先生成一个Person对象,并将对象在内存中的 
//索引赋值给this关键字,此时可以通过this关键字操作新生成的对象,如下面的添加属性或方法 
this.name = name; //this关键字不能少。为当前对象,即this关键字引用的对象的name属性赋值 
//,实际相当于为当前对象添加name属性后,再为其name属性赋值。 
this.age = age; 
this.showName = function(){ //为当前对象添加方法 
alert(this.name); 
} 
this.showAge = function(){ 
alert(this.age); 
} 
//将当前对象返回给赋值符号左边的变量(不必明确使用return) 
} 
var obj1 = new Person("Koji", 22); //生成一个Person对象 
var obj2 = new Person("Luo", 21); 
obj1.showName(); //Koji 
obj1.showAge(); //22 
obj2.showName(); //Luo 
obj2.showAge(); //21 
</script>

构造函数的方式和工厂方式一样,会为每个对象创建独享的函数对象。当然也可以将这些函数

对象定义在构造函数外面,这样又有了对象和方法相互独立的问题。

原型方法:该方法利用的对象的prototype属性

script type="text/javascript"> function Person(){} //定义一个空构造函数,且不能传递参数 
//将所有的属性的方法都赋予prototype属性 
Person.prototype.name = "Koji"; //添加属性 
Person.prototype.age = 22; 
Person.prototype.showName = function(){ //添加方法 
alert(this.name); 
} 
Person.prototype.showAge = function(){ 
alert(this.age); 
} 
var obj1 = new Person(); //生成一个Person对象 
var obj2 = new Person(); 
obj1.showName(); //Koji 
obj1.showAge(); //22 
obj2.showName(); //Koji 
obj2.showAge(); //22 
</script>

当生成Person对象的时候prototype的属性都赋值给了新的对象。那么属性和方法是共享的。

该方法的问题首先是构造函数不能传参,每个新生成的对象都有默认值。其次,方法共享没有

任何问题,但是属性共享就有问题,当属性是可改变状态的对象的时候。

<script type="text/javascript"> function Person(){} //定义一个空构造函数,且不能传递参数 
Person.prototype.age = 22; 
Person.prototype.array = new Array("Koji", "Luo"); 
Person.prototype.showAge = function(){ 
alert(this.age); 
} 
Person.prototype.showArray = function(){ 
alert(this.array); 
} 
var obj1 = new Person(); //生成一个Person对象 
var obj2 = new Person(); 
obj1.array.push("Kyo"); //向obj1的array属性添加一个元素 
obj1.showArray(); //Koji,Luo,Kyo 
obj2.showArray(); //Koji,Luo,Kyo 
</script>

上面的代码通过obj1向obj1的属性array添加元素的时候,obj2的arra属性的元素也跟着受到

影响,原因就在于obj1和obj2对象的array属性引用的是同一个Array对象,那么改变这个Array

对象,另一引用该Array对象的属性自然也会受到影响

混合的构造函数/原型方式

使用构造函数定义对象的属性,使用原型(prototype)定义对象的方法,这样就可以做到属性

私有,而方法共享。

<script type="text/javascript"> function Person(name, age) { 
this.name = name; 
this.age = age; 
this.array = new Array("Koji", "Luo"); 
} 
Person.prototype.showName = function() { 
alert(this.name); 
} 
Person.prototype.showArray = function() { 
alert(this.array); 
} 
var obj1 = new Person("Koji", 22); //生成一个Person对象 
var obj2 = new Person("Luo", 21); 
obj1.array.push("Kyo"); //向obj1的array属性添加一个元素 
obj1.showArray(); //Koji,Luo,Kyo 
obj1.showName(); //Koji 
obj2.showArray(); //Koji,Luo 
obj2.showName(); //Luo 
</script>

属性私有后,改变各自的属性不会影响别的对象。同时,方法也是由各个对象共享。在语义上,

这符合了面相对象编程的要求。

动态原型方法

<script type="text/javascript"> function Person(name, age) { 
this.name = name; 
this.age = age; 
this.array = new Array("Koji", "Luo"); 
//如果Person对象中的_initialized为undefined,表明还没有为Person的原型添加方法 
if (typeof Person._initialized == "undefined") 
{ 
Person.prototype.showName = function() { 
alert(this.name); 
} 
Person.prototype.showArray = function() { 
alert(this.array); 
} 
Person._initialized = true; //设置为true,不必再为prototype添加方法 
} 
} 
var obj1 = new Person("Koji", 22); //生成一个Person对象 
var obj2 = new Person("Luo", 21); 
obj1.array.push("Kyo"); //向obj1的array属性添加一个元素 
obj1.showArray(); //Koji,Luo,Kyo 
obj1.showName(); //Koji 
obj2.showArray(); //Koji,Luo 
obj2.showName(); //Luo 
</script>

这种方法和构造函数/原型方式大同小异。只是将方法的添加放到了构造函数之中,同时在构造

函数Person上添加了一个属性用来保证if语句只能成功执行一次

在实际应用中采用最广泛的是构造函数/原型方法。动态原型方法也很流行,它在功能上和构造

函数/原型方法是等价的。不要单独使用构造函数或原型方法。

Javascript 相关文章推荐
javascript实现轮显新闻标题链接
Aug 13 Javascript
js jquery数组介绍
Jul 15 Javascript
web前端开发JQuery常用实例代码片段(50个)
Aug 28 Javascript
Javascript的表单验证-揭开正则表达式的面纱
Mar 18 Javascript
JS实现响应鼠标点击动画渐变弹出层效果代码
Mar 25 Javascript
用JavaScript动态建立或增加CSS样式表的实现方法
May 20 Javascript
微信小程序 地图定位简单实例
Oct 14 Javascript
js 打开新页面在屏幕中间的实现方法
Nov 02 Javascript
使用Angular CLI从蓝本生成代码详解
Mar 24 Javascript
Angular Material Icon使用详解
Nov 07 Javascript
使用js实现单链解决前端队列问题的方法
Feb 03 Javascript
jQuery带控制按钮轮播图插件
Jul 31 jQuery
Jquery创建层显示标题和内容且随鼠标移动而移动
Jan 26 #Javascript
js加入收藏以及使用Jquery更改透明度
Jan 26 #Javascript
JS对象转换为Jquery对象示例
Jan 26 #Javascript
JavaScript原型链示例分享
Jan 26 #Javascript
JS设置获取cookies的方法
Jan 26 #Javascript
js中小数转换整数的方法
Jan 26 #Javascript
javascript中取前n天日期的两种方法分享
Jan 26 #Javascript
You might like
PHP 编程请选择正确的文本编辑软件
2006/12/21 PHP
PHP CURL或file_get_contents获取网页标题的代码及两者效率的稳定性问题
2015/11/30 PHP
PHP中静态变量的使用方法实例分析
2016/12/01 PHP
phpmyadmin下载、安装、配置教程
2017/05/16 PHP
PHP实现求解最长公共子串问题的方法
2017/11/17 PHP
PHP ob缓存以及ob函数原理实例解析
2020/11/13 PHP
JavaScript在IE和Firefox(火狐)的不兼容问题解决方法小结
2010/04/13 Javascript
特殊情况下如何获取span里面的值
2014/05/20 Javascript
基于JavaScript实现文字超出部分隐藏
2016/02/29 Javascript
jquery使用Cookie和JSON记录用户最近浏览历史
2016/04/19 Javascript
AngularJS 防止页面闪烁的方法
2017/03/09 Javascript
js实现图片旋转 js滚动鼠标中间对图片放大缩小
2017/07/05 Javascript
浅谈关于axios和session的一些事
2017/07/13 Javascript
Vue 滚动行为的具体使用方法
2017/09/13 Javascript
webpack将js打包后的map文件详解
2018/02/22 Javascript
file-loader打包图片文件时路径错误输出为[object-module]的解决方法
2020/01/03 Javascript
微信小程序自定义支持图片的弹窗
2020/12/21 Javascript
[54:54]Newbee vs Serenity 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/18 DOTA
更改Python命令行交互提示符的方法
2015/01/14 Python
浅谈Python中的闭包
2015/07/08 Python
深入解析Python中的urllib2模块
2015/11/13 Python
利用Anaconda完美解决Python 2与python 3的共存问题
2017/05/25 Python
Python+selenium实现截图图片并保存截取的图片
2018/01/05 Python
解决pytorch GPU 计算过程中出现内存耗尽的问题
2019/08/19 Python
关于python tushare Tkinter构建的简单股票可视化查询系统(Beta v0.13)
2020/10/19 Python
Lyle & Scott苏格兰金鹰官网:英国皇室御用品牌
2018/05/09 全球购物
环境科学专业个人求职的自我评价
2013/11/28 职场文书
大学生实习感言
2014/01/16 职场文书
校园文化建设方案
2014/02/03 职场文书
应届生求职自荐信
2014/07/04 职场文书
乡镇保密工作责任书
2014/07/28 职场文书
股权转让协议范本
2014/12/07 职场文书
学校元旦晚会开场白
2014/12/14 职场文书
校友回访母校寄语
2015/02/26 职场文书
使用nginx动态转换图片大小生成缩略图
2021/03/31 Servers
2021年国产动漫公司排行前十名,玄机科技上榜,第二推出过铠甲勇士
2022/03/18 杂记