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 相关文章推荐
js不完美解决click和dblclick事件冲突问题
Jul 16 Javascript
Java/JS获取flash高宽的具体方法
Dec 27 Javascript
js中的cookie的读写操作示例详解
Apr 17 Javascript
Egret引擎开发指南之视觉编程
Sep 03 Javascript
七个不允许错过的jQuery小技巧
Dec 21 Javascript
javascript实现九宫格相加数值相等
May 28 Javascript
javascript学习指南之回调问题
Apr 23 Javascript
JavaScript中用let语句声明作用域的用法讲解
May 20 Javascript
JavaScript表单焦点自动切换代码
Jul 24 Javascript
详解如何用typescript开发koa2的二三事
Nov 13 Javascript
koa大型web项目中使用路由装饰器的方法示例
Apr 02 Javascript
p5.js码绘“跳动的小正方形”的实现代码
Oct 22 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
PHP两种快速排序算法实例
2015/02/15 PHP
php mysql_list_dbs()函数用法示例
2017/03/29 PHP
详解PHP PDO简单教程
2019/05/28 PHP
javascript编程起步(第六课)
2007/01/10 Javascript
javascript根据时间生成m位随机数最大13位
2014/10/30 Javascript
JS显示日历和天气的方法
2016/03/01 Javascript
关于iframe跨域POST提交的方法示例
2017/01/15 Javascript
JavaScript调试之console.log调试的一个小技巧分享
2017/08/07 Javascript
VUE前端cookie简单操作
2017/10/17 Javascript
Vue精简版风格指南(推荐)
2018/01/30 Javascript
jQuery替换节点元素的操作方法
2018/03/18 jQuery
Vue 将后台传过来的带html字段的字符串转换为 HTML
2018/03/29 Javascript
LayUi使用switch开关,动态的去控制它是否被启用的方法
2019/09/21 Javascript
JavaScript实现商品评价五星好评
2020/11/30 Javascript
Python程序员鲜为人知但你应该知道的17个问题
2014/06/04 Python
Python文件操作,open读写文件,追加文本内容实例
2016/12/14 Python
Python变量和数据类型详解
2017/02/15 Python
Python中%r和%s的详解及区别
2017/03/16 Python
Python实现的维尼吉亚密码算法示例
2018/04/12 Python
python实现linux下抓包并存库功能
2018/07/18 Python
python爬虫之遍历单个域名
2019/11/20 Python
使用OpenCV实现道路车辆计数的使用方法
2020/07/15 Python
Python爬虫简单运用爬取代理IP的实现
2020/12/01 Python
一款纯css3实现的响应式导航
2014/10/31 HTML / CSS
瑞典首都斯德哥尔摩的多元奢侈时尚品牌:Acne Studios
2017/07/09 全球购物
POP文化和音乐灵感的时尚:Hot Topic
2019/06/19 全球购物
北京振戎融通Java面试题
2015/09/03 面试题
高中生毕业自我鉴定
2013/10/10 职场文书
C++程序员求职信范文
2014/04/14 职场文书
挂职个人工作总结
2015/03/05 职场文书
2015年小学财务工作总结
2015/07/20 职场文书
Python控制台输出俄罗斯方块的方法实例
2021/04/17 Python
Python中else的三种使用场景
2021/06/16 Python
面试提问mysql一张表到底能存多少数据
2022/03/13 MySQL
Python学习之包与模块详解
2022/03/19 Python
MySQL 原理与优化之原数据锁的应用
2022/08/14 MySQL