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 checkbox 全选/反选及批量删除
Apr 28 Javascript
Jquery实现搜索框提示功能示例代码
Aug 13 Javascript
浅析Cookie中的Path与domain
Dec 18 Javascript
用js正确判断用户名cookie是否存在的方法
Jan 28 Javascript
JavaScript中的函数重载深入理解
Aug 04 Javascript
Bootstrap实现input控件失去焦点时验证
Aug 04 Javascript
JavaScript“尽快失败”的原则实例详解
Oct 08 Javascript
jQuery实现 上升、下降、删除、添加一行代码
Mar 06 Javascript
jackson解析json字符串,首字母大写会自动转为小写的方法
Dec 22 Javascript
微信小程序实现image组件图片自适应宽度比例显示的方法
Jan 16 Javascript
基于Vue实现的多条件筛选功能的详解(类似京东和淘宝功能)
May 07 Javascript
JavaScript实现简单日历效果
Sep 11 Javascript
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
Redis使用Eval多个键值自增的操作实例
2016/11/04 PHP
php与c 实现按行读取文件实例代码
2017/01/03 PHP
php微信公众号开发之校园图书馆
2018/10/20 PHP
解决php扩展安装不生效问题
2019/10/25 PHP
JSON 教程 json入门学习笔记
2020/09/22 Javascript
javascript开发技术大全-第3章 js数据类型
2011/07/03 Javascript
js String对象中常用方法小结(字符串操作)
2012/01/27 Javascript
D3.js 从P元素的创建开始(显示可加载数据)
2014/10/30 Javascript
详解AngularJS中自定义过滤器
2015/12/28 Javascript
jQuery使用cookie与json简单实现购物车功能
2016/04/15 Javascript
Bootstrap编写一个兼容主流浏览器的受众巨幕式风格页面
2016/07/01 Javascript
简单封装js的dom查询实例代码
2016/07/08 Javascript
快速搭建vue2.0+boostrap项目的方法
2018/04/09 Javascript
基于Vue 服务端Cookies删除的问题
2018/09/21 Javascript
mock.js模拟前后台交互
2019/07/25 Javascript
将RGB值转换为灰度值的简单算法
2019/10/09 Javascript
深入webpack打包原理及loader和plugin的实现
2020/05/06 Javascript
[02:20]DOTA2中文配音宣传片
2013/05/22 DOTA
[28:57]EG vs VGJ.T 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/16 DOTA
Python 稀疏矩阵-sparse 存储和转换
2017/05/27 Python
JS设计模式之责任链模式实例详解
2018/02/03 Python
Python代码块批量添加Tab缩进的方法
2018/06/25 Python
Python将json文件写入ES数据库的方法
2019/04/10 Python
Python整数对象实现原理详解
2019/07/01 Python
django Admin文档生成器使用详解
2019/07/22 Python
什么是python的列表推导式
2020/05/26 Python
关于python3.7安装matplotlib始终无法成功的问题的解决
2020/07/28 Python
使用Python爬取小姐姐图片(beautifulsoup法)
2021/02/11 Python
中国央视网签名寄语
2014/01/18 职场文书
2014党员干部四风问题对照检查材料思想汇报
2014/09/24 职场文书
销售员工作检讨书(推荐篇)
2014/10/18 职场文书
公司管理制度范本
2015/08/03 职场文书
2016年小学生新年寄语
2015/08/18 职场文书
python基于scrapy爬取京东笔记本电脑数据并进行简单处理和分析
2021/04/14 Python
JavaScript实现班级抽签小程序
2021/05/19 Javascript
深入理解 Golang 的字符串
2022/05/04 Golang