JavaScript Objects in Detail
JavaScript’s core—most often used and most fundamental—data type is the Object data type. JavaScript has one complex data type, the Object data type, and it has five simple data types: Number, String, Boolean, Undefined, and Null. Note that these simple (primitive) data types are immutable (cannot be changed), while objects are mutable (can be changed).
What is an Object
An object is an unordered list of primitive data types (and sometimes reference data types) that is stored as a series of name-value pairs. Each item in the list is called a property (functions are called methods).
Consider this simple object:
var myFirstObject = {firstName: "Richard", favoriteAuthor: "Conrad"};
Think of an object as a list that contains items, and each item (a property or a method) in the list is stored by a name-value pair. The property names in the example above are firstName and favoriteAuthor. And the values are “Richard” and “Conrad.”
Property names can be a string or a number, but if the property name is a number, it has to be accessed with the bracket notation. More on bracket notation later. Here is another example of objects with numbers as the property name:
var ageGroup = {30: "Children", 100:"Very Old"};
console.log(ageGroup.30) // This will throw an error
// This is how you will access the value of the property 30, to get value "Children"
console.log(ageGroup["30"]); // Children
//It is best to avoid using numbers as property names.
As a JavaScript developer you will most often use the object data type, mostly for storing data and for creating your own custom methods and functions.
Reference Data Type and Primitive Data Types
One of the main differences between reference data type and primitive data types is reference data type’s value is stored as a reference, it is not stored directly on the variable, as a value, as the primitive data types are. For example:
// The primitive data type String is stored as a value
var person = "Kobe";
var anotherPerson = person; // anotherPerson = the value of person
person = "Bryant"; // value of person changed
console.log(anotherPerson); // Kobe
console.log(person); // Bryant
It is worth noting that even though we changed person to “Bryant,” the anotherPerson variable still retains the value that person had.
Compare the primitive data saved-as-value demonstrated above with the save-as-reference for objects:
var person = {name: "Kobe"};
var anotherPerson = person;
person.name = "Bryant";
console.log(anotherPerson.name); // Bryant
console.log(person.name); // Bryant
In this example, we copied the person object to anotherPerson, but because the value in person was stored as a reference and not an actual value, when we changed the person.name property to “Bryant” the anotherPerson reflected the change because it never stored an actual copy of it’s own value of the person’s properties, it only had a reference to it.
Object Data Properties Have Attributes
Each data property (object property that store data) has not only the name-value pair, but also 3 attributes (the three attributes are set to true by default):
—
Configurable Attribute: Specifies whether the property can be deleted or changed.
— Enumerable: Specifies whether the property can be returned in a for/in loop.
— Writable: Specifies whether the property can be changed.
Note that ECMAScript 5 specifies accessor properties along with the data properties noted above. And the accessor properties are functions (getters and setters). We will learn more about ECMAScript 5 in an already-scheduled post slated for February 15.
Creating Objects
These are the two common ways to create objects:
- Object Literals
The most common and, indeed, the easiest way to create objects is with the object literal described here:// This is an empty object initialized using the object literal notation
var myBooks = {};
// This is an object with 4 items, again using object literal
var mango = {
color: "yellow",
shape: "round",
sweetness: 8,
howSweetAmI: function () {
console.log("Hmm Hmm Good");
}
} - Object Constructor
The second most common way to create objects is with Object constructor. A constructor is a function used for initializing new objects, and you use the new keyword to call the constructor.var mango = new Object ();
mango.color = "yellow";
mango.shape= "round";
mango.sweetness = 8;
mango.howSweetAmI = function () {
console.log("Hmm Hmm Good");
}While you can use some reserved word such as “for” as property names in your objects, it is wise to avoid this altogether.
Objects can contain any other data type, including Numbers, Arrays, and even other Objects.
Practical Patterns for Creating Objects
For simple objects that may only ever be used once in your application to store data, the two methods used above would suffice for creating objects.
Imagine you have an application that displays fruits and detail about each fruit. All fruits in your application have these properties: color, shape, sweetness, cost, and a showName function. It would be quite tedious and counterproductive to type the following every time you want to create a new fruit object.
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);
});
}
}
If you have 10 fruits, you will have to add the same code 10 times. And what if you had to make a change to the nativeTo function? You will have to make the change in 10 different places. Now extrapolate this to adding objects for members on a website and suddenly you realized the manner in which we have created objects so far is not ideal objects that will have instances, particularly when developing large applications.
To solve these repetitive problems, software engineers have invented patterns (solutions for repetitive and common tasks) to make developing applications more efficient and streamlined.
Here are two common patterns for creating objects. If you have done the Learn JavaScript Properly course, you would have seen the lessons in the Code Academy used this first pattern frequently:
1.Constructor Pattern for Creating Objects
- 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);
});
}
}
With this pattern in place, it is very easy to create all sorts of fruits. Thus:
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.
If you had to change the fruitName function, you only had to do it in one location. The pattern encapsulates all the functionalities and characteristics of all the fruits in by making just the single Fruit function with inheritance.
Notes:
— An inherited property is defined on the object’s prototype property. For example: someObject.prototype.firstName = “rich”;
— An own property is defined directly on the object itself, for example:
// Let’s create an object first:
var aMango = new Fruit ();
// Now we define the mangoSpice property directly on the aMango object
// Because we define the mangoSpice property directly on the aMango object, it is an own property of aMango, not an inherited property.
aMango.mangoSpice = “some value”;
— To access a property of an object, we use object.property, for example:
console.log(aMango.mangoSpice); // “some value”
— To invoke a method of an object, we use object.method(), for example
:
// First, lets add a method
aMango.printStuff = function () {return “Printing”;}
// Now we can invoke the printStuff method:
aMango.printStuff ();
2.Prototype Pattern for Creating Objects
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);
}
And this is how we call the Fruit () constructor in this prototype pattern:
var mangoFruit = new Fruit ();
mangoFruit.showName(); //
mangoFruit.nativeTo();
// This is a Generic Fruit
// Grown in:USA
Further Reading
For a complete discussion on these two patterns and a thorough explanation of how each work and the disadvantages of each, read Chapter 6 of Professional JavaScript for Web Developers. You will also learn which pattern Zakas recommends as the best one to use (Hint: it is neither of the 2 above).
How to Access Properties on an Object
The two primary ways of accessing properties of an object are with dot notation and bracket notation.
1.Dot Notation
// We have been using dot notation so far in the examples above, here is another example again:
var book = {title: "Ways to Go", pages: 280, bookMark1:"Page 20"};
// To access the properties of the book object with dot notation, you do this:
console.log ( book.title); // Ways to Go
console.log ( book.pages); //
2.Bracket Notation
// To access the properties of the book object with bracket notation, you do this:
console.log ( book["title"]); //Ways to Go
console.log ( book["pages"]); // 280
//Or, in case you have the property name in a variable:
var bookTitle = "title";
console.log ( book[bookTitle]); // Ways to Go
console.log (book["bookMark" + 1]); // Page 20
Accessing a property on an object that does not exist will result in undefined.
Own and Inherited Properties
Objects have inherited properties and own properties. The own properties are properties that were defined on the object, while the inherited properties were inherited from the object’s Prototype object.
To find out if a property exists on an object (either as an inherited or an own property), you use the in operator:
// Create a new school object with a property name schoolName
var school = {schoolName:"MIT"};
// Prints true because schoolName is an own property on the school object
console.log("schoolName" in school); // true
// Prints false because we did not define a schoolType property on the school object, and neither did the object inherit a schoolType property from its prototype object Object.prototype.
console.log("schoolType" in school); // false // Prints true because the school object inherited the toString method from Object.prototype.
console.log("toString" in school); // true
hasOwnProperty
To find out if an object has a specific property as one of its own property, you use the hasOwnProperty method. This method is very useful because from time to time you need to enumerate an object and you want only the own properties, not the inherited ones.
// Create a new school object with a property name schoolName
var school = {schoolName:"MIT"};
// Prints true because schoolName is an own property on the school object
console.log(school.hasOwnProperty ("schoolName")); // true // Prints false because the school object inherited the toString method from Object.prototype, therefore toString is not an own property of the school object.
console.log(school.hasOwnProperty ("toString")); // false
Accessing and Enumerating Properties on Objects
To access the enumerable (own and inherited) properties on objects, you use the for/in loop or a general for loop.
// Create a new school object with 3 own properties: schoolName, schoolAccredited, and schoolLocation.
var school = {schoolName:"MIT", schoolAccredited: true, schoolLocation:"Massachusetts"};
//Use of the for/in loop to access the properties in the school object
for (var eachItem in school) {
console.log(eachItem); // Prints schoolName, schoolAccredited, schoolLocation
}
Accessing Inherited Properties
Properties inherited from Object.prototype are not enumerable, so the for/in loop does not show them. However, inherited properties that are enumerable are revealed in the for/in loop iteration.
For example:
//Use of the for/in loop to access the properties in the school object
for (var eachItem in school) {
console.log(eachItem); // Prints schoolName, schoolAccredited, schoolLocation
}
// Create a new HigherLearning function that the school object will inherit from.
/* SIDE NOTE: As Wilson (an astute reader) correctly pointed out in the comments below, the educationLevel property is not actually inherited by objects that use the HigherLearning constructor; instead, the educationLevel property is created as a new property on each object that uses the HigherLearning constructor. The reason the property is not inherited is because we use of the "this" keyword to define the property.
*/
function HigherLearning () {
this.educationLevel = "University";
}
// Implement inheritance with the HigherLearning constructor
var school = new HigherLearning ();
school.schoolName = "MIT";
school.schoolAccredited = true;
school.schoolLocation = "Massachusetts";
//Use of the for/in loop to access the properties in the school object
for (var eachItem in school) {
console.log(eachItem); // Prints educationLevel, schoolName, schoolAccredited, and schoolLocation
}
In the last example, note the educationLevel property that was defined on the HigherLearning function is listed as one of the school’s properties, even though educationLevel is not an own property—it was inherited.
Object’s Prototype Attribute and Prototype Property
The prototype attribute and prototype property of an object are critically important concepts to understand in JavaScript. Read my post JavaScript Prototype in Plain, Detailed Language for more.
Deleting Properties of an Object
To delete a property from an object, you use the delete operator. You cannot delete properties that were inherited, nor can you delete properties with their attributes set to configurable. You must delete the inherited properties on the prototype object (where the properties were defined). Also, you cannot delete properties of the global object, which were declared with the var keyword.
The delete operator returns true if the delete was successful. And surprisingly, it also returns true if the property to delete was nonexistent or the property could not be deleted (such as non-configurable or not owned by the object).
These examples illustrate:
var christmasList = {mike:"Book", jason:"sweater" }
delete christmasList.mike; // deletes the mike property
for (var people in christmasList) {
console.log(people);
}
// Prints only jason
// The mike property was deleted
delete christmasList.toString; // returns true, but toString not deleted because it is an inherited method
// Here we call the toString method and it works just fine—wasn’t deleted
christmasList.toString(); //"[object Object]"
// You can delete a property of an instance if the property is an own property of that instance. For example, we can delete the educationLevel property from the school's object we created above because the educationLevel property is defined on the instance: we used the "this" keyword to define the property when we declare the HigherLearning function. We did not define the educationLevel property on the HigherLearning function's prototype.
console.log(school.hasOwnProperty("educationLevel")); true
// educationLevel is an own property on school, so we can delete it
delete school.educationLevel; true
// The educationLevel property was deleted from the school instance
console.log(school.educationLevel); undefined
// But the educationLevel property is still on the HigherLearning function
var newSchool = new HigherLearning ();
console.log(newSchool.educationLevel); // University
// If we had defined a property on the HigherLearning function's prototype, such as this educationLevel2 property:
HigherLearning.prototype.educationLevel2 = "University 2";
// Then the educationLevel2 property on the instances of HigherLearning would not be own property.
// The educationLevel2 property is not an own property on the school instance
console.log(school.hasOwnProperty("educationLevel2")); false
console.log(school.educationLevel2); // University 2
// Let's try to delete the inherited educationLevel2 property
delete school.educationLevel2; true (always returns true, as noted earlier)
// The inherited educationLevel2 property was not deleted
console.log(school.educationLevel2); University 2
Serialize and Deserialize Objects
To transfer your objects via HTTP or to otherwise convert it to a string, you will need to serialize it (convert it to a string); you can use the JSON.stringify function to serialize your objects. Note that prior to ECMAScript 5, you had to use a popular json2 library (by Douglas Crockford) to get the JSON.stringify function. It is now standardized in ECMAScript 5.
To Deserialize your object (convert it to an object from a string), you use the JSON.parse function from the same json2 library. This function too has been standardized by ECMAScript 5.
JSON.stringify Examples:
var christmasList = {mike:"Book", jason:"sweater", chelsea:"iPad" }
JSON.stringify (christmasList);
// Prints this string:
// "{"mike":"Book","jason":"sweater","chels":"iPad"}"
// To print a stringified object with formatting, add "null" and "4" as parameters:
JSON.stringify (christmasList, null, 4);
// "{
"mike": "Book",
"jason": "sweater",
"chels": "iPad"
}"
// JSON.parse Examples \\
// The following is a JSON string, so we cannot access the properties with dot notation (like christmasListStr.mike)
var christmasListStr = '{"mike":"Book","jason":"sweater","chels":"iPad"}';
// Let’s convert it to an object
var christmasListObj = JSON.parse (christmasListStr);
// Now that it is an object, we use dot notation
console.log(christmasListObj.mike); // Book
For more detailed coverage of JavaScript Objects, including ECMAScript 5 additions for dealing with objects, read chapter 6 of JavaScript: The Definitive Guide 6th Edition.
JavaScript Objects in Detail的更多相关文章
- Post Complex JavaScript Objects to ASP.NET MVC Controllers
http://www.nickriggs.com/posts/post-complex-javascript-objects-to-asp-net-mvc-controllers/ Post ...
- Passing JavaScript Objects to Managed Code
Silverlight If the target managed property or input parameter is strongly typed (that is, not typed ...
- dinoql 使用graphql 语法查询javascript objects
dinoql 是一个不错的基于graphql 语法查询javascript objects 的工具包,包含以下特性 graphql 语法(很灵活) 安全的访问(当keys 不存在的时候,不会抛出运行时 ...
- [Immutable.js] Using fromJS() to Convert Plain JavaScript Objects into Immutable Data
Immutable.js offers the fromJS() method to build immutable structures from objects and array. Object ...
- [Javascript] Understanding the .constructor property on JavaScript Objects
Constructor functions hold an interesting purpose in JavaScript. Unlike in classical languages, they ...
- 通俗易懂的语言描述JavaScript原型
这是一个翻译.原文地址http://javascriptissexy.com/javascript-prototype-in-plain-detailed-language/# 原型(prototyp ...
- JavaScript Prototype in Plain Language
非常好的文章: http://javascriptissexy.com/javascript-prototype-in-plain-detailed-language/ jan. 25 2013 14 ...
- JavaScript 特殊对象 Array-Like Objects 详解
这篇文章拖了有两周,今天来跟大家聊聊 JavaScript 中一类特殊的对象 -> Array-Like Objects. (本文节选自 underscore 源码解读系列文章,完整版请关注 h ...
- C++程序员的javascript教程
本文主要目的是向c++程序员阐述javascript的编程思想,以及编程中的误区. 变量声明: 1.变量声明的解析早于代码运行.JavaScript引擎的工作方式是,先解析代码,获取所有被声明的变 ...
随机推荐
- javascript对象初探 (五)--- 函数对象的属性
与其他对象相同的是,函数对象中也有一个叫做constructor的属性,其引用就是Function()这个构造函数. function her(a){ return a; } console.log( ...
- 邁向IT專家成功之路的三十則鐵律 鐵律八:IT人學習之道-基礎功
修練過中國武術的人都知道,任何一種拳法的學習最重要的就是基礎功,而基礎功又可分為內在與外在的修練,內在的修練強調在平心.靜氣.不爭的調息.至於外在這首重在站樁.鬆沉.不疾不徐的應對能力.有了深厚基礎的 ...
- 在Dev GridControl中添加颜色可变的ProgressBar z
在使用DevExpress,GridControl自带的ProgressBarControl的时候 由于无法通过BackColor/ForeColor来改变进度条的颜色所以很多特效是实现不了的.如下面 ...
- MYSQL查询的四种情况
1 普通连接查询 select 表1字段1,表2字段2,from 表1,表2,where 表1.字段1==表2.字段2 2 inner join查询 select 表1字段1 ,表2字段2,from ...
- log4net菜鸟指南
log4net的作用 提供一个记录日志的框架,可以将日志信息记录到文件(txt.xml等).控制台.Windows事件日志和数据库(MSSQL.Acess.Oracle.DB2和SQLite等). 要 ...
- Android自己定义ViewGroup打造各种风格的SlidingMenu
看鸿洋大大的QQ5.0側滑菜单的视频课程,对于側滑的时的动画效果的实现有了新的认识,似乎打通了任督二脉.眼下能够实现随意效果的側滑菜单了.感谢鸿洋大大!! 鸿洋大大用的是HorizontalScrol ...
- sql的一些知识_where
简单相同查询,查询age=22的三列信息,并按照降序排列 ORDER BY weight DESC 此外,where还支持一下判断操作符 值得注意的是,如果比较的值为数值,则不需要加引号,如果是字符, ...
- 找top 10信息
本文章内容来源于<程序猿面试宝典>. 题目: 有1千万条短信,以文本文件的形式保存.一行一条,有反复.请用5分钟时间,找出反复出现最多的前10条. 解析: 某些面试者想用数据库的办法来实现 ...
- MySQL 建立外键约束
http://www.jzxue.com/shujuku/mysql/201109/06-8742.html MySQL 建立外键约束的语法太晦涩难懂了, 不得不记下笔记. 1. 在建表时建立外键 C ...
- 关于mysql的表名/字段名/字段值是否区分大小写的问题
http://www.2cto.com/database/201202/121253.html 1.mysql默认情况下是否区分大小写,使用show Variables like '%table_na ...