var mangoFruit = { color: "yellow", sweetness: 8, fruitName: "Mango", nativeToLand: ["South America", "Central America"], showName: function () { console.log("This is " + this.fruitName); }, nativeTo: function () { this.nativeToLand.forEach(function (eachCountry) { console.log("Grown in:" + eachCountry); }); } }
如果你有10个水果,你就得添加10次相同的代码。并且,如果想修改nativeTo函数,就得在10个不同的地方进行修改。再进一步推想,如果你在开发一个大型网站,你为上面的对象都一个一个添加了属性。但是,你突然发现你创建对象的方式不是很理想,你想要进行修改,这时又该怎么办。
为了解决这些重复性的问题,软件工程师们发明了各种模式(对于重复问题和常见任务的解决方案),使用开发程序更有效率和合理化。
下面是两种创建对象的常用模式:
1.构造方法模式
function Fruit (theColor, theSweetness, theFruitName, theNativeToLand) { this.color = theColor; this.sweetness = theSweetness; this.fruitName = theFruitName; this.nativeToLand = theNativeToLand; this.showName = function () { console.log("This is a " + this.fruitName); } this.nativeTo = function () { this.nativeToLand.forEach(function (eachCountry) { console.log("Grown in:" + eachCountry); }); } }
使用这种模式,很容易就可以创建出各式各样的水果来。像这样:
var mangoFruit = new Fruit ("Yellow", 8, "Mango", ["South America", "Central America", "West Africa"]); mangoFruit.showName(); // This is a Mango. mangoFruit.nativeTo(); //Grown in:South America // Grown in:Central America // Grown in:West Africa var pineappleFruit = new Fruit ("Brown", 5, "Pineapple", ["United States"]); pineappleFruit.showName(); // This is a Pineapple.
如果你要改变属性或方法,你只需要在一个地方进行修改就可以了。这个模式通过一个Fruit函数的继承,封装了所有水果的功能和特性。
注意:
◦可继承的属性需要定义在对象的prototype对象属性上。比如
someObject.prototype.firstName = "rich";
◦属于自身的属性要直接定义在对象的上。比如:
// 首先,创建一个对象 var aMango = new Fruit (); // 接着,直接在对象上定义mongoSpice方法 // 因为我们直接在对象身上定义了mangoSpice属性,所以它是aMango自身的属性,不是一个可继承的属性 aMango.mangoSpice = “some value”;
◦要访问一个对象的属性,使用object.property,如:
console.log(aMango.mangoSpice); // "some value"
◦要调用一个对象的方法,使用object.method(),如:
// 首先,增加一个方法 aMango.printStuff = function() { return "Printing"; } // 现在,可以调用printStuff方法 aMango.printStuff();
2.原型模式
function Fruit () { } Fruit.prototype.color = "Yellow"; Fruit.prototype.sweetness = 7; Fruit.prototype.fruitName = "Generic Fruit"; Fruit.prototype.nativeToLand = "USA"; Fruit.prototype.showName = function () { console.log("This is a " + this.fruitName); } Fruit.prototype.nativeTo = function () { console.log("Grown in:" + this.nativeToLand); }
下面是在原型模式中调用Fruit()构造函数的方法:
var mangoFruit = new Fruit (); mangoFruit.showName(); // mangoFruit.nativeTo(); // This is a Generic Fruit // Grown in:USA
扩展阅读
如果需要了解这两种模式的更详细的解释,可以阅读《JavaScript高级程序设计》的第六章,其中详细讨论了这两种方法的优缺点。书中还讨论了除这两个外的其它模式。
如何访问对象中的属性
访问对象属性的两种主要方法是点记法(dot notation)和中括号记法(bracket notation)。
1.点记法
// 这是我们前面例子中一直使用的访问属性的方法 var book = {title: "Ways to Go", pages: 280, bookMark1:"Page 20"}; // 使用点记法访问book对象的title和pages属性: console.log ( book.title); // Ways to Go console.log ( book.pages); // 280
2.中括号记法