JavaScript创建对象的几种方式
2016-04-15 16:35
489 查看
面向对象(Object-Oriented,OO)语言都有一个标志,那就是它们都具有类的概念,而通过类可以创建任意多个具有相同属性和方法的对象。而我们知道,ECMAScript中没有类的概念,因此它的对象也与基于类的语言中的对象有所不同。我们可以把ECMA的对象想象成散列表:无非就是一组名值对,其中值可以是数据或函数。
一、最简单的方式
创建自定义对象最简单的方式就是创建一个Object的实例,然后再为它添加属性和方法,如下所示。
二、对象字面量方式
早期的JavaScript开发人员经常使用这个模式创建新对象,几年后,对象字面量称为创建这种对象的首选模式。前面的例子用对象字面量语法可以写成这样:
这个例子中的person对象和前面例子中的person对象是一样的。
三、工厂模式
虽然Object构造函数或对象字面量都可以用来创建单个对象,但这些方式有个明显的缺点:使用同一个接口创建很多对象,会产生大量重复代码。为了解决这个问题,人们开始使用工厂模式的一种变体。
工厂模式是软件工程领域一种广为人知的设计模式,这种设计模式抽象了创建具体对象的过程。考虑到ECMAScript中无法创建类,开发人员就发明了一种函数,用来封装以特定接口创建对象的细节,如下:
可以看到,工厂模式虽然解决开了创建多个相似对象的问题,但却美誉解决对象识别的问题,于是,有一个新模式出现了。
四、构造函数模式
you know,ECMAScript中的构造函数可以用来创建特定类型的对象。像Object和Array这样的原生构造哈数,在运行时会自动出现在执行环境中。此外,也可以创建自定义的构造函数,从而定义自定义对象类型的属性和方法。例如,可以用构造函数将前面的例子重写如下:
按照惯例,构造函数始终都应该以一个大写字母开头,而非构造函数则应以小写字母开头。主要是为了区分,因为构造函数本身也是函数,只不过可以用来创建对象而已。
用 new 操作符的方式调用构造函数实际上会经历以下 4 个步骤:
(1)创建一个新对象
(2)将构造函数的作用域赋给新对象(因此this就指向了这个新对象)
(3)执行构造函数中的代码
(4)返回新对象
在例子的最后,person1和person2分别保存着person的一个不同的实例。这两个对象都有一个constructor(构造函数)属性,该属性指向person。但是如果执行如下语句,会返回false:
应为每个person的实例都包含了一个不同Function的实例,因此不同实例上的同名函数是不相等的,创建两个完成同样任务的Function也的确没有必要,因此原型模式诞生了。
五、原型模式和构造函数模式组合使用
我们创建的每一个函数都有一个prototype指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有势力共享的属性和方法。也就是对象实例的原型对象。具体创建方法如下:
这种模式是最成熟也是最常用的模式。
当然还有一些不常用的模式,比如寄生构造函数模式以及稳妥构造函数模式,由于这两种模式存在无法使用instanceof操作符确定对象类型的问题,所以一般不建议使用。
一、最简单的方式
创建自定义对象最简单的方式就是创建一个Object的实例,然后再为它添加属性和方法,如下所示。
var person = new Object(); person.name = "liuchang"; person.age = 23; person.job = "Software Engineer"; person.sayName = function(){ alert(this.name); }
二、对象字面量方式
早期的JavaScript开发人员经常使用这个模式创建新对象,几年后,对象字面量称为创建这种对象的首选模式。前面的例子用对象字面量语法可以写成这样:
var person = { name: "liuchang", age: 23, job: "Software Engineer", sayName: function(){ alert(this.name); } }
这个例子中的person对象和前面例子中的person对象是一样的。
三、工厂模式
虽然Object构造函数或对象字面量都可以用来创建单个对象,但这些方式有个明显的缺点:使用同一个接口创建很多对象,会产生大量重复代码。为了解决这个问题,人们开始使用工厂模式的一种变体。
工厂模式是软件工程领域一种广为人知的设计模式,这种设计模式抽象了创建具体对象的过程。考虑到ECMAScript中无法创建类,开发人员就发明了一种函数,用来封装以特定接口创建对象的细节,如下:
function creatPerson(name, age, job){ var o = new Object(); o.name = name; o.age = age; o.job = job; o.sayName = function(){ alert(this.name); } return o; } var person1 = creatPerson("liucha 4000 ng",23,"Software Engineer"); var person2 = creatPerson("alex",25,"Web Designer");
可以看到,工厂模式虽然解决开了创建多个相似对象的问题,但却美誉解决对象识别的问题,于是,有一个新模式出现了。
四、构造函数模式
you know,ECMAScript中的构造函数可以用来创建特定类型的对象。像Object和Array这样的原生构造哈数,在运行时会自动出现在执行环境中。此外,也可以创建自定义的构造函数,从而定义自定义对象类型的属性和方法。例如,可以用构造函数将前面的例子重写如下:
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.sayName = function(){ alert(this.name); } } var person1 = new Person("liuchang",23,"Software Engineer"); var person2 = new Person("alex",25,"Web Designer");
按照惯例,构造函数始终都应该以一个大写字母开头,而非构造函数则应以小写字母开头。主要是为了区分,因为构造函数本身也是函数,只不过可以用来创建对象而已。
用 new 操作符的方式调用构造函数实际上会经历以下 4 个步骤:
(1)创建一个新对象
(2)将构造函数的作用域赋给新对象(因此this就指向了这个新对象)
(3)执行构造函数中的代码
(4)返回新对象
在例子的最后,person1和person2分别保存着person的一个不同的实例。这两个对象都有一个constructor(构造函数)属性,该属性指向person。但是如果执行如下语句,会返回false:
alert(person1.sarName == person2.sayName); //false
应为每个person的实例都包含了一个不同Function的实例,因此不同实例上的同名函数是不相等的,创建两个完成同样任务的Function也的确没有必要,因此原型模式诞生了。
五、原型模式和构造函数模式组合使用
我们创建的每一个函数都有一个prototype指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有势力共享的属性和方法。也就是对象实例的原型对象。具体创建方法如下:
function(name, age, job){ this.name = name; this.age = age; this.job = job; } person.prototype.sayName = function(){ alert(this.name); }
这种模式是最成熟也是最常用的模式。
当然还有一些不常用的模式,比如寄生构造函数模式以及稳妥构造函数模式,由于这两种模式存在无法使用instanceof操作符确定对象类型的问题,所以一般不建议使用。
相关文章推荐
- JQuery1——基础($对象,选择器,对象转换)
- Android学习笔记(二九):嵌入浏览器
- Android java 与 javascript互访(相互调用)的方法例子
- JavaScript演示排序算法
- javascript实现10进制转为N进制数
- 设计模式之创建型模式 - 特别的变量问题
- 最后一次说说闭包
- Ajax
- 2019年开发人员应该学习的8个JavaScript框架
- HTML中的script标签研究
- 对一个分号引发的错误研究
- 异步流程控制:7 行代码学会 co 模块
- ES6 走马观花(ECMAScript2015 新特性)
- JavaScript拆分字符串时产生空字符的原因
- Canvas 在高清屏下绘制图片变模糊的解决方法
- Redux系列02:一个炒鸡简单的react+redux例子
- JavaScript 各种遍历方式详解