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

方法一:原始方法
代码如下:

<script>
var obj = new Object();
obj.name = "Kitty";//为对象增加属性
obj.age = 21;
obj.showName = function () {//为对象添加方法
console.log(this.name);
};
obj.showAge = function(){
console.log(this.age);
};
obj.showName();
obj.showAge();
</script>
      这种方法通过new关键字生成一个对象,然后根据JavaScript是动态语言的特性来添加属性和方法,构造一个对象。其中的this表示调用该方法的对象。

这种方法的问题在于:如果我们需要多次创建对象,那么就需要重复代码多次,不利于代码的复用。

方法二:工厂方法
代码如下:

<script>
function createObj(){
var obj = new Object();//创建对象
obj.name = "Kitty";
obj.age = "21";
obj.showName = function () {
console.log(this.name);
};
obj.showAge = function () {
console.log(this.age);
};
return obj;
}

var obj1 = createObj();
var obj2 = createObj();

obj1.showName();
obj1.showAge();

obj2.showName();
obj2.showAge();
</script>
       这种方法虽然也实现了创建对象,但是同样地,如果需要多次创建对象,而且属性内容不一样的话,也是需要重复代码多遍。需要重新考虑代码重用率,接下来修改代码,使其可以提高代码重复率,而且可以改变工厂方法,传入参数赋值。
改进代码如下:

<script>
function createObj(name,age){
var obj = new Object();
obj.name = name;
obj.age = age;
obj.showName = function () {
console.log(this.name);
};
obj.showAge = function(){
console.log(this.age);
};

return obj;
}

var obj1 = new createObj("Kitty","21");
var obj2 = new createObj("Luo","22");

obj1.showName();//Kitty
obj1.showAge();//21

obj2.showName();//luo
obj2.showAge();//22
</script>
      这种方法虽然可以提高代码的重用率,但和面向对象中类的概念相比,有一个很大的缺陷。面向对象强调对象的属性私有,但对象的方法是共享。而上面的工厂方法在创建对象时,要为每个对象创建各自私有的方法。同时,由于为每个对象都创建逻辑相同的方法,所以很浪费内存。
改进代码如下:

<script>
function createObj(name,age){
var obj = new Object();
obj.name = name;
obj.age = age;
obj.showName = showName;
obj.showAge = showAge;
return obj;
}

function showName(){
console.log(this.name);
}
function showAge(){
console.log(this.age);
}

var obj1 = new createObj("Kitty","21");
var obj2 = new createObj("Luo","22");

obj1.showName();//Kitty
obj1.showAge();//21

obj2.showName();//luo
obj2.showAge();//22
</script>
      上面通过定义几个函数对象,解决了不同对象持有函数对象的私有问题。现在所有对象的方法都持有上面两个函数的引用。但是这么一来,对象的函数和对象又相互独立,这和面向对象中特定方法属于特定类的思想不符合。

方法三:构造函数方法
代码如下:

<script>
function Person(name,age){
this.name = name;
this.age = age;

this.showName = function () {
console.log(this.name);
};
this.showAge = function () {
console.log(this.age);
};
}
var obj1 = new Person("Kitty","21");
var obj2 = new Person("Luo","22");

obj1.showName();//Kitty
obj1.showAge();//21

obj2.showName();//luo
obj2.showAge();//22
</script>
     构造函数的方法和工厂方法一样,会为每个对象创建独享的函数对象。当然也可以将这些函数对象定义在构造函数外面,这样有了对象和方法相互独立的问题。

使用构造函数存在的最大问题就是每个实例都会将所有的属性创建一次。这个对于数值属性来说可以接受,但是如果函数方法每个实例都要创建一遍,则不合理。

要创建Person()的新实例,必须使用new操作符。以这种方式调用构造函数实际上会经历以下四个步骤:

创建一个新对象;
将构造函数的作用域赋给新对象(因此this就指向了这个新对象);
执行构造函数中的代码(为这个新对象添加属性);
返回新对象。

方法四:原型方法    
代码如下:

<script>
function Person(){} //定义一个空构造函数,且不能传递参数
//将所有的属性的方法都赋予prototype
Person.prototype.name = "Kitty";
Person.prototype.age = 21;
Person.prototype.showName = function (){
console.log(this.name);
};
Person.prototype.showAge = function (){
console.log(this.age);
};

var obj1 = new Person("Kitty","21");
var obj2 = new Person("Luo","22");

obj1.showName();//Kitty
obj1.showAge();//21

obj2.showName();//luo
obj2.showAge();//22
</script>
      当生成Person对象时,prototype的属性都赋给了新的对象。那么属性和方法是共享的。首先,该方法的问题是构造函数不能传递参数,每个新生成的对象都有默认值。其次,方法共享没有任何问题,但是,当属性是可改变状态的对象时,属性共享就有问题。
修改代码如下:

<script>
function Person(){} //定义一个空构造函数,且不能传递参数
//将所有的属性的方法都赋予prototype
Person.prototype.age = 21;
Person.prototype.array = new Array("Kitty","luo");

Person.prototype.showAge = function (){
console.log(this.age);
};
Person.prototype.showArray = function (){
console.log(this.array);
};
var obj1 = new Person();
var obj2 = new Person();
obj1.array.push("Wendy");//向obj1的array属性添加一个元素

obj1.showArray();//Kitty,luo,Wendy
obj2.showArray();//Kitty,luo,Wendy
</script>
     上面的代码通过obj1的属性array添加元素时,obj2的array属性的元素也跟着受到影响,原因就在于obj1和obj2对象的array属性引用的是同一个Array对象,那么改变这个Array对象,另一引用该Array对象的属性自然也会受到影响,混合的构造函数/原型方式使用构造函数定义对象的属性,使用原型方法定义对象的方法,这样就可以做到属性私有,而方法共享。

方法五:混合的构造函数/原型方式
代码如下:

<script>
function Person(name,age){
this.name = name;
this.age = age;
this.array = new Array("Kitty","luo");
}

Person.prototype.showName = function (){
console.log(this.name);
};
Person.prototype.showArray = function (){
console.log(this.array);
};
var obj1 = new Person("Kitty",21);
var obj2 = new Person("luo",22);
obj1.array.push("Wendy");//向obj1的array属性添加一个元素

obj1.showArray();//Kitty,luo,Wendy
obj1.showName();//Kitty
obj2.showArray();//Kitty,luo
obj2.showName();//luo
</script>
      属性私有后,改变各自的属性不会影响别的对象。同时,方法也是由各个对象共享的。在语义上,这符合了面向对象编程的要求。

方法六:动态原型方法
代码如下:

<script>
function Person(name,age){
this.name = name;
this.age = age;
this.array = new Array("Kitty","luo");
//如果Person对象中_initialized 为undefined,表明还没有为Person的原型添加方法
if(typeof Person._initialized == "undefined"){
Person.prototype.showName = function () {
console.log(this.name);
};
Person.prototype.showArray = function () {
console.log(this.array);
};
Person._initialized = true;
}
}

var obj1 = new Person("Kitty",21);
var obj2 = new Person("luo",22);
obj1.array.push("Wendy");//向obj1的array属性添加一个元素

obj1.showArray();//Kitty,luo,Wendy
obj1.showName();//Kitty
obj2.showArray();//Kitty,luo
obj2.showName();//luo
</script>
      这种方法和构造函数/原型方式大同小异。只是将方法的添加放到了构造函数之中,同时在构造函数Person上添加了一个属性用来保证if语句只能成功执行一次,在实际应用中,采用最广泛的构造函数/原型方法。动态原型方法也很流行,它在功能上和构造函数/原型方法是等价的。不要单独使用构造函数和原型方法。

原文链接:https://blog.csdn.net/u010297791/article/details/55670841

JavaScript如何创建一个对象的更多相关文章

  1. Javascript 中创建自定义对象的方法(设计模式)

    Javascript 中创建对象,可以有很多种方法. Object构造函数/对象字面量: 抛开设计模式不谈,使用最基本的方法,就是先调用Object构造函数创建一个对象,然后给对象添加属性. var ...

  2. 【JavaScript学习】JavaScript对象创建

    1.最简单的方法,创建一个对象,然后添加属性 var person = new Object(); person.age = 23; person.name = "David"; ...

  3. 深入JavaScript对象创建的细节

    最近深入学习javascript后,有个体会:面向对象的方式编程才是高效灵活的编程,也是现在唯一可以让代码更加健壮的编程方式.如果我们抛开那些玄乎的抽象出类等等思想,我自己对面向对象的从写程序的角度理 ...

  4. JavaScript中创建类,赋值给ajax中的data参数

    缘由:因为要给根据是否选中checkbox来动态增加ajax中data的属性(ajax的data属性格式的几种方法,参考http://www.jb51.net/article/46676.htm) d ...

  5. 李洪强iOS开发之OC[008] -创建一个对象并访问实例变量

    // //  main.m //  07 - 创建一个对象并且访问实例变量 // //  Created by vic fan on 16/7/3. //  Copyright © 2016年 李洪强 ...

  6. JavaScript中创建字典对象(dictionary)实例

    这篇文章主要介绍了JavaScript中创建字典对象(dictionary)实例,本文直接给出了实现的源码,并给出了使用示例,需要的朋友可以参考下 对于JavaScript来说,其自身的Array对象 ...

  7. 简单使用JSON,JavaScript中创建 JSON 对象(一)

    JSON:JavaScript 对象表示法(JavaScript Object Notation). JSON 是存储和交换文本信息的语法.类似 XML. JSON 比 XML 更小.更快,更易解析. ...

  8. [笔试题目]使用Stringbuffer无 参的构造函数创建 一个对象时,默认的初始容量是多少? 如果长度不够使用了,自动增长多少倍?

    [笔试题目] 使用Stringbuffer无 参的构造函数创建 一个对象时,默认的初始容量是多少? 如果长度不够使用了,自动增长多少倍? StringBuffer 底层是依赖了一个字符数组才能存储字符 ...

  9. JavaScript Cookies,创建,获取cookies value

    什么是cookie? cookie 是存储于访问者的计算机中的变量.每当同一台计算机通过浏览器请求某个页面时,就会发送这个 cookie.你可以使用 JavaScript 来创建和取回 cookie ...

随机推荐

  1. Kong04- Kong 四大参考说明

    Kong 四大参考说明 Kong 的官方有很多详细的参考说明,比如配置文件.命令行.Admin API.代理.负载均衡,接下来我们简单看一下,都提供什么内容. 本文主要基于 Kong 1.3 版本进行 ...

  2. Logback MDC

    Mapped Diagnostic Contexts (MDC)   (译:诊断上下文映射) Logback的设计目标之一是审计和调试复杂的分布式应用程序.大多数实际的分布式系统需要同时处理来自多个客 ...

  3. [考试反思]0928csp-s模拟测试54:转瞬

    咕了好久,也没什么想说的. 下一场就又爆炸了... T3特判打丢一句话丢了14分,剩下其实都还好. T1:x 给我的第一感觉是建图找联通块,但既然只要找联通块为什么不直接并查集呢? 对于每一个数字合并 ...

  4. 划艇:dp/组合数/区间离散化

    Description 在首尔城中,汉江横贯东西.在汉江的北岸,从西向东星星点点地分布着 N 个划艇学校,编号依次为 1 到 N.每个学校都拥有若干艘划艇.同一所学校的所有划艇颜色相同,不同的学校的划 ...

  5. NOIP模拟 26

    我辛辛苦苦敲了3.5h的码 得分和一份8B的码一样多 自闭555. T1 marshland 最小费用可行流, 板子不会,建图更不会. 当然是用暴搜得到0分的好成绩啦 补了补板子. %了%RNB. 学 ...

  6. NOIP模拟赛18 皇帝的烦恼O(∩_∩)O 二分+DP

    题目描述 经过多年的杀戮,秦皇终于统一了中国.为了抵御外来的侵略,他准备在国土边境安置n名将军.不幸的是这n名将军羽翼渐丰,开始展露他们的狼子野心了.他们拒绝述职.拒绝接受皇帝的圣旨. 秦皇已经准备好 ...

  7. js 重写a标签的href属性和onclick事件

    适应场景:假如移动端拨打电话,需要给a标签添加href属性,但是由于需求,需要链接跳转的同时给a标签添加onclick事件,如果不做任何处理的话,默认执行点击事件,而不会跳转href属性的链接. 怎么 ...

  8. js设置Date

    function getDate (yyyy, MM, dd) { let t = new Date() t.setFullYear(yyyy) t.setMonth(Number(MM) - 1) ...

  9. python面试看这一篇就够了

    python-面试通关宝典 有面Python开发方向的,看这一个repo就够啦? 语言特性 1.谈谈对 Python 和其他语言的区别 Python属于解释型语言,当程序运行时,是一行一行的解释,并运 ...

  10. Requests库使用总结

    概述 Requests是python中一个很Pythonic的HTTP库,用于构建HTTP请求与解析响应 Requests开发哲学 Beautiful is better than ugly.(美丽优 ...