本文详细介绍JavaScript中创建对象的四种常用方式:使用Object构造函数、对象字面量、工厂模式以及构造函数模式。重点解析构造函数与普通函数的区别、new操作符的执行过程,并通过代码示例对比各模式的优缺点,探讨内存共享与原型模式的基础概念。
JavaScript对象创建概述
本文通过具体实例,深入解析JavaScript中面向对象编程里对象创建的几种典型方法,旨在为读者提供清晰的参考与学习思路。
在JavaScript开发中,创建对象存在多种常用途径,了解这些方式有助于根据具体场景选择最合适的方案。
第一种方法是利用Object构造函数或对象字面量语法来创建对象,这是最基础且直观的手段。
第二种方法是采用工厂模式来创建对象,通过封装函数来批量生成具有相似属性的对象实例。
第三种方法是使用构造函数模式,通过自定义构造函数并配合new操作符来实例化对象。
第四种方法是基于原型模式创建对象,利用prototype属性实现属性和方法的共享,优化内存使用。
基础方式:Object与字面量
接下来详细讲解第一种方法:使用Object构造函数或对象字面量语法。
使用Object构造函数是创建对象的一种基础方式,通过new关键字实例化Object并手动赋值属性。
var student = new Object();
student.name = "easy";
student.age = "20";
使用对象字面量则是更简洁的写法,直接通过大括号定义键值对来创建对象,代码更为紧凑。
var sutdent = {
name : "easy",
age : 20
};
工厂模式与构造函数模式
第二种方法:工厂模式创建对象,通过定义一个函数来封装创建对象的逻辑,从而避免重复代码。
function createStudent(name, age) {
var obj = new Object();
obj.name = name;
obj.age = age;
return obj;
}
var student1 = createStudent("easy1", 20);
var student2 = createStudent("easy2", 20);
...
var studentn = createStudent("easyn", 20);
第三种方法:构造函数模式创建对象,这是JavaScript中实现面向对象编程的核心机制之一。
在之前创建Object等原生对象时,实际上已经接触过其构造函数,例如通过new关键字实例化。
var obj = new Object();
在创建原生数组Array类型的对象时,同样使用了其构造函数,指定初始长度或元素。
var arr = new Array(10); //构造一个初始长度为10的数组对象
为了深入理解构造函数模式,首先需要明确构造函数与普通函数之间的核心区别。
第一点区别在于调用方式:构造函数并没有特殊的语法定义,任何函数只要使用new操作符调用,即可视为构造函数;反之,若不使用new调用,则仅为普通函数。
第二点区别在于命名约定:通常构造函数名称首字母大写,而普通函数首字母小写,这种约定有助于在代码中直观区分二者,例如new Array()和new Object()。
第三点区别在于执行流程:使用new操作符调用构造函数时,会经历四个阶段:(1)在内存中创建一个新对象;(2)将构造函数的作用域赋给新对象,使this指向该新对象;(3)执行构造函数内的代码,为对象添加属性和方法;(4)返回新创建的对象。
基于对构造函数与普通函数区别的理解,我们可以将之前的工厂模式函数改写为构造函数形式,并添加方法属性。
function Student(name, age) {
this.name = name;
this.age = age;
this.alertName = function(){
alert(this.name)
};
}
function Fruit(name, color) {
this.name = name;
this.color = color;
this.alertName = function(){
alert(this.name)
};
}
通过上述构造函数,我们可以分别创建Student和Fruit类型的对象实例。
var v1 = new Student("easy", 20);
var v2 = new Fruit("apple", "green");
此时,我们可以使用instanceof操作符来检测上述对象的类型,从而准确区分Student和Fruit对象。
alert(v1 instanceof Student); //true
alert(v2 instanceof Student); //false
alert(v1 instanceof Fruit); //false
alert(v2 instanceof Fruit); //true
alert(v1 instanceof Object); //true 任何对象均继承自Object
alert(v2 instanceof Object); //true 任何对象均继承自Object
为了优化代码,可以将Student和Fruit对象中相同的方法提取到构造函数外部。
function Student(name, age) {
this.name = name;
this.age = age;
}
function Fruit(name, color) {
this.name = name;
this.color = color;
};
function alertName() {
alert(this.name);
}
我们将alertName()函数定义为全局函数,使对象中的alertName属性指向该全局函数的引用。这样,stu1和stu2共享了同一个全局函数,从而解决了内存浪费的问题。
然而,通过定义全局函数来解决对象内部共享问题并非最佳实践。如果此类全局函数过多,将破坏自定义对象封装的初衷,导致命名空间污染。
因此,更好的解决方案是利用原型对象模式来解决共享问题。
原型模式创建对象
第四种方法:原型模式创建对象,这是JavaScript中实现属性共享的关键机制。
原型链及原型继承是JavaScript中最复杂且难以理解的部分之一。由于本课程定位,若对JavaScript原型机制感兴趣,建议查阅相关高级JS原型知识点资料。
function Student() {
this.name = 'easy';
this.age = 20;
}
Student.prototype.alertName = function(){
alert(this.name);
};
var stu1 = new Student();
var stu2 = new Student();
stu1.alertName(); //easy
stu2.alertName(); //easy
alert(stu1.alertName == stu2.alertName); //true 二者共享同一函数
感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.jb51.net/code/HtmlJsRun测试上述代码的运行效果。
更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》。
希望本文所述的JavaScript对象创建方法对大家的学习和实践有所帮助。