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高级程序设计(第3版)学习笔记10 再访js对象
Oct 11 Javascript
confirm确认对话框的实现方法总结
Jun 17 Javascript
AngularJS基础 ng-value 指令简单示例
Aug 03 Javascript
微信小程序 location API接口详解及实例代码
Oct 12 Javascript
Javascript+CSS3实现进度条效果
Oct 28 Javascript
微信小程序 解决请求服务器手机预览请求不到数据的方法
Jan 04 Javascript
详解vue.js2.0父组件点击触发子组件方法
May 10 Javascript
Angular2 http jsonp的实例详解
Aug 31 Javascript
vue中的计算属性的使用和vue实例的方法示例
Dec 04 Javascript
BootStrap自定义popover,点击区域隐藏功能的实现
Jan 23 Javascript
JS实现简单获取最近7天和最近3天日期的方法
Apr 18 Javascript
React配置子路由的实现
Jun 03 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
IP138 IP地址查询小偷实现代码
2010/02/15 PHP
解析php中array_merge与array+array的区别
2013/06/21 PHP
php curl抓取网页的介绍和推广及使用CURL抓取淘宝页面集成方法
2015/11/30 PHP
PHP生成图像验证码的方法小结(2种方法)
2016/07/18 PHP
分享别人写的一个小型js框架
2007/08/13 Javascript
使用javascript为网页增加夜间模式
2014/01/26 Javascript
ExtJS判断IE浏览器类型的方法
2014/02/10 Javascript
javascript 回到顶部效果的实现代码
2014/02/17 Javascript
JavaScript中用getDate()方法返回指定日期的教程
2015/06/09 Javascript
基于javascript bootstrap实现生日日期联动选择
2016/04/07 Javascript
微信小程序 MD5的方法详解及实例代码
2017/03/10 Javascript
vue.js之vue-cli脚手架的搭建详解
2017/05/05 Javascript
vue2的todolist入门小项目的详细解析
2017/05/11 Javascript
详解Webstorm 新建.vue文件支持高亮vue语法和es6语法
2017/10/26 Javascript
2020京东618叠蛋糕js脚本(亲测好用)
2020/06/02 Javascript
Vue指令实现OutClick的示例
2020/11/16 Javascript
Python的包管理器pip更换软件源的方法详解
2016/06/20 Python
wxpython中Textctrl回车事件无效的解决方法
2016/07/21 Python
python PyTorch预训练示例
2018/02/11 Python
Python编写一个优美的下载器
2018/04/15 Python
python assert的用处示例详解
2019/04/01 Python
pandas中ix的使用详细讲解
2020/03/09 Python
python实现感知机模型的示例
2020/09/30 Python
CSS3中border-radius属性设定圆角的使用技巧
2016/05/10 HTML / CSS
Final类有什么特点
2012/04/25 面试题
培训讲师邀请函
2014/01/10 职场文书
租房协议书
2014/04/10 职场文书
贷款担保申请书
2014/05/20 职场文书
竞聘自述材料
2014/08/25 职场文书
四查四看整改措施
2014/09/19 职场文书
毕业生银行实习自我鉴定
2014/10/14 职场文书
初中生散播谣言检讨书
2014/11/17 职场文书
2015年教师节新闻稿
2015/07/17 职场文书
创业计划书之冷饮店
2019/09/27 职场文书
Vue如何清空对象
2022/03/03 Vue.js
td 内容自动换行 table表格td设置宽度后文字太多自动换行
2022/12/24 HTML / CSS