本篇体验通过硬编码、工厂模式、构造函数来创建JavaScript对象。
□ 通过硬编码创建JavaScript对象
当需要创建一个JavaScript对象时,我们可能这样写:
var person = {firstName: "Darren",lastName: "Ji",getFullName: function() {return this.firstName + " " + this.lastName;}};
如果需要创建2个结构相同的对象,我们可能这样写:
var person = {firstName: "Darren",lastName: "Ji",getFullName: function() {return this.firstName + " " + this.lastName;}};var person2 = {firstName: "Darren2",lastName: "Ji2",getFullName: function () {return this.firstName + " " + this.lastName;}};
□ 通过工厂模式创建JavaScript对象
但实际上,还可以通过工厂模式来创建JavaScript对象。
var person1 = createPerson("Darren1", "Ji1"),person2 = createPerson("Darren2", "Ji2");function createPerson(firstName, lastName) {return {firstName: firstName,lastName: lastName,getFullName: function() {return this.firstName + " " + this.lastName;}};}
继续在createPerson函数中增加一个方法,并调用。
var person1 = createPerson("Darren1", "Ji1"),person2 = createPerson("Darren2", "Ji2");alert(person1.greet(person2));function createPerson(firstName, lastName) {return {firstName: firstName,lastName: lastName,getFullName: function() {return this.firstName + " " + this.lastName;},greet: function(person) {if (typeof person.getFullName !== "undefined") {return "hello, " + person.getFullName();} else {return "are u here?";}}};}
输出结果:hello, Darren2 Ji2
如果person1.greet方法的实参为匿名对象,如下:
alert(person1.greet({}));
输出结果:are u here?
□ 通过构造函数创建JavaScript对象
就像通过var arr = new Array()创建数组对象,通过var date = new Date()创建日期对象,JavaScript允许我们创建自定义数据类型。
var Person = function(firstName, lastName) {this.firstName = firstName;this.lastName = lastName;this.getFullName = function() {return this.firstName + " " + this.lastName;};this.greet = function(person) {if (person instanceof Person) {return "hello, " + person.getFullName();} else {return "are u here?";}};};var person1 = new Person("Darren", "Ji"),person2 = new Person("Jack", "Zhang");alert(person1.greet({getFullName: "this is string"}));
输出结果:are u here?
○ 变量Peson的第一个字母大写,这是一个惯例,表示Peson是自定义数据类型
○ this表示Person对象
○ instanceof用来判断变量是否是某种数据类型
○ 通过new来创建数据类型对象,new关键字不可获取,否则,在本例中this会指向window
○ 因为person1.greet()的实参不是Peson类型,所以输出了are u here?
如果把最后一行代码改成:
alert(person1.greet(person2));
输出结果:hello, Jack Zhang
但这里还有一点小问题:getFullName和greet可看作是对象,每次通过new创建Peson对象时,相当于在内存上创建了2份的Peson对象,以及2份的getFullName和greet对象,这增加了内存开销。是否可以让getFullName和greet放到一个公共的地方,然后每个Peson对象都可以引用他们呢?--prototype属性此时就可以用上了!
var Person = function(firstName, lastName) {this.firstName = firstName;this.lastName = lastName;};Person.prototype.getFullName = function () {return this.firstName + " " + this.lastName;};Person.prototype.greet = function (person) {if (person instanceof Person) {return "hello, " + person.getFullName();} else {return "are u here?";}};var person1 = new Person("Darren", "Ji"),person2 = new Person("Jack", "Zhang");alert(person1.greet(person2));
输出结果:hello, Jack Zhang
以上,在Peson的prototype属性上定义的方法,能够被每个Peson对象共享,这从一定程度上减少了内存开销。
“JavaScript进阶系列”包括: