JS面向对象设计-创建对象
程序员文章站
2022-03-26 12:20:47
Object构造函数和对象字面量都可以用来创建单个对象,但是在创建多个对象时,会产生大量重复代码. 1.工厂模式 工厂模式抽象了创建具体对象的过程.由于ECMAScript无法创建类,我们用函数来封装 以特定接口创建对象 的细节. 2.构造函数模式 用来创建特定类型的对象,比如Object/Arr ......
object构造函数和对象字面量都可以用来创建单个对象,但是在创建多个对象时,会产生大量重复代码.
1.工厂模式
工厂模式抽象了创建具体对象的过程.由于ecmascript无法创建类,我们用函数来封装以特定接口创建对象的细节.
function createperson(name, age, job) { var o = new object(); o.name = name; o.age = age; o.job = job; o.sayname = function() { console.log(this.name); } return o; } // 根据接收到的参数,构建一个包含三个属性一个方法的对象,并返回 var person1 = createperson("zhu", 26, "fe");
ps. 工厂模式解决了创建多个相似对象的问题,却无法识别对象(对象的类型)
2.构造函数模式
用来创建特定类型的对象,比如object/array这样的原生构造函数,或者自定义构造函数(可以自定义对象类型的属性和方法).
/* 1.没有显示创建对象 * 2.直接将属性和方法赋值给this对象 * 3.没有return语句 * 4.首字母大写(区别于ecmascript中其他函数,构造函数本身也是函数,只不过可以创建对象) */ function person(name, age, job) { this.name = name; this.age = age; this.job = job; this.sayname = function() { console.log(this.name); } } // 必须使用new操作符 var person1 = new person("zhu", 26, "fe"); var person2 = new person("liu", 23, "java");
2.1 调用该总种构造函数会经历四个步骤
- 创建一个新对象
- 将构造函数的作用域赋给新对象(因此this就指向了这个新对象)
- 执行构造函数中的代码(为这个新对象添加属性)
- 返回新对象
2.2 对象类型
- person1,person2分别保存着person的一个不同实例,两个对象都有constructor(构造函数)属性指向person.
js person1.constructor == person, person2.constructor == person // true
-
person1,person2既是object实例也是person实例.
// 所有对象均继承自object person1 instanceof object, person1 instanceof person // true person2 instanceof object, person2 instanceof person // true
ps. 创建自定义构造函数意味着可以将它的实例标识为一种特定的类型.
2.3 将构造函数当作函数
构造函数与普通函数的区别在于调用它们的方式不同,只要通过new操作符调用,它就可以作为构造函数.
// 当作构造函数使用,使用new操作符来创建一个新对象. var person = new person("zhu", 26, "fe"); person.sayname(); // 作为普通函数调用,属性和方法都被添加到window对象. // 在全局作用域中调用一个函数时,this对象总是指向global对象(在浏览器中就是window对象) person("zhu", 26, "fe"); window.sayname(); // 使用call()或者apply()在某个特定对象的作用域中调用 var o = new object(); person.call(o, "zhu", 26, "fe"); o.sayname();
ps. 构造函数模式定义的构造函数是定义在global对象中的.
2.4 构造函数的问题
每个方法都要在每个实例上重新创建一遍,person1和person2的同名sayname方法不是同一个function的实例.
ps. ecmascript的函数是对象,因此每定义一个函数,也就实例化一个对象.即每个person实例都包含一个不同function实例.
// 逻辑上的构造函数可以这样定义 function person(name, age) { this.name = name; this.age = age; this.sayname = new function() { console.log(this.name); } }
没有必要创建两个完成同样任务的function实例,然而将sayname提到全局虽然解决做同一件事的问题,但是实际上只能被某个对象调用,而且可能需要定义很多全局函数(无封装性).