我们可以利用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. phpStorm //todo 的用途

    用phpstorm看到别人的代码使用了注释//todo,且todo是彩色的 我想这个应该是有点用的吧,于是百度了下,大概是可能由于某些原因,导致部分代码没有写.但又怕忘了, 用//todo就可以做提示 ...

  2. [BZOJ4553][HEOI2016/TJOI2016]序列

    传送门 好像是DP再套个裸的CDQ? 树套树是不可能写树套树的,这辈子都不可能写树套树的 对于一个 \(i\) ,设它最小为 \(a_i\) ,原数为 \(b_i\) ,最大为 \(c_i\) \(f ...

  3. python 爬取猫眼电影top100数据

    最近有爬虫相关的需求,所以上B站找了个视频(链接在文末)看了一下,做了一个小程序出来,大体上没有修改,只是在最后的存储上,由txt换成了excel. 简要需求:爬虫爬取 猫眼电影TOP100榜单 数据 ...

  4. Promise对象及它在js中的执行顺序

    关于Promise对象的学习及它的执行顺序 学习阮一峰老师的ES6入门后的记录 1.promise的定义 promise是一个对象,通常包裹着一个异步操作,promise对象提供一些接口的方法,返回一 ...

  5. Project Euler 57: Square root convergents

    五十七.平方根收敛(Square root convergents) 二的平方根可以表示为以下这个无穷连分数: \[ \sqrt 2 =1+ \frac 1 {2+ \frac 1 {2 +\frac ...

  6. [LINQ2Dapper]最完整Dapper To Linq框架(五)---查看Linq实际执行的SQL

    此例子是使用LINQ2Dapper封装,效率优于EntityFramwork,并且支持.NetFramework和.NetCore框架,只依赖于Dapper支持.net framework4.6.1及 ...

  7. vue cli3.0^版本处理文件下载的问题

    downloadFile(url, fileName) { axios.get(url, { responseType: 'blob' }) .then(({ data }) => { // 为 ...

  8. docker项目——搭建飞机大战小游戏

    项目2:搭建打飞机小游戏,验证数据持久化(最底下有链接) 第一步:拉取镜像 [root@localhost docker-image]# docker load < httpd_img.tar. ...

  9. IDEA Debug 无法进入断点的解决方法

    文章来源: https://studyidea.cn/idea_breakpoint_not_use 前言 某个多模块项目中使用多个版本的 Spring,如 Spring 4,Spring 5,在使用 ...

  10. Python数据可视化之matplotlib

    常用模块导入 import numpy as np import matplotlib import matplotlib.mlab as mlab import matplotlib.pyplot ...