6.6 KiB
6.6 KiB
Chapter 6. Objects
6.1 Introduction to Objects
- An object is an unordererd collection of properties (each is a name/value pair)
- JS object can inherit properties from another object (aka "prototype")
- JS objects are dynamic; i.e. properties can be added/removed
- Any value in JS is object except string, number, Symbol,
true
/false
,null
/undefined
- Objects are mutable, and manupulated by reference rather than value.
- e.g.
let y=x
meansy
holds a reference to the same obj, not a copy of that obj.
- e.g.
- Common operations on obj: create, set, query, delete, test, and enumerate
- Property has name & value, but no obj has two properties with the same name (that's why we use Symbol)
- JS use own property to refer to non-inherited properties.
- Each property has 3 property attributes:
- writable: whether value of property can be set
- enumerable: whether the property name is returned by for/in loop
- configurable: whether the property can be deleted and its attributes can be altered
6.2 Creating Objects
Creating obj, 4 methods:
- using object literal
- using keyword
new
- using
Object.create()
function
6.2.1 Object Literals
Object literal in simplest form:
- comma-separated list of colon-separated
name:value
pairs, enclosed within{}
.- property name: JS identifier or string
- property value: JS expression
let empty = {}; // An object with no properties
let point = { x: 0, y: 0 }; // Two numeric properties
let p2 = { x: point.x, y: point.y+1 }; // More complex values
let book = {
"main title": "JavaScript", // These property names include spaces,
"sub-title": "The Definitive Guide", // and hyphens, so use string literals.
for: "all audiences", // for is reserved, but no quotes.
author: { // The value of this property is
firstname: "David", // itself an object.
surname: "Flanagan"
}
};
When object literal works:
- Object literal creates & initializes a new & distinct obj every time it's evaluated.
- In loop body, a new obj can be created repeatedly.
6.2.2 Creating Objects with new
new
operator- creates & initialize a new object
- syntax:
new
followed by function invocation as constructor
let o = new Object(); // Create an empty object: same as {}.
let a = new Array(); // Create an empty array: same as [].
let d = new Date(); // Create a Date object representing the current time
let r = new Map(); // Create a Map object for key/value mapping
6.2.3 Prototypes
Almost all JS obj has a prototype associate with it:
- All objs created using object literal (shown in 6.2.1) are associated with the same prototype obj, referred by
Object.prototype
- objs created using
new
(invoking constructor) use value of constructor function'sprototype
property as prototypenew Object()
inherits fromObject.prototype
new Array()
inherits fromArray.prototype
- Only few objects have
prototype
property, they are used to defineprototypes
for all other objs.
6.2.4 Object.create()
3 Methods below demonstrated ability to create a new obj with an arbitrary prototype:
- Create new obj w/ defined prototype using
Object.create()
let o1 = Object.create({x: 1, y: 2}); // o1 inherits properties x and y.
o1.x + o1.y // => 3
- Create new obj w/o prototype by parsing
null
- Created obj inherit no property or method (e.g.
toString()
)
- Created obj inherit no property or method (e.g.
let o2 = Object.create(null); // o2 inherits no props or methods.
- Create ordinary new empty obj using
Object.prototype
(like obj returned by{}
orObject()
)
let o3 = Object.create(Object.prototype); // o3 is like {} or new Object().
Use created object to guard unintended modification
- Q: How to guard against unintended modification of an obj by a function (from other library)?
- A: Instead of passing the obj directly to the function, pass an obj that inherit from it. So writing property do not affect original value. (like passing a read-only)
let o = { x: "don't change this value" };
library.function(Object.create(o)); // Guard against accidental modifications
6.3 Querying and Setting Properties
Obtain value of property:
- using dot (
.
): RHS of dot should be simple identifier (not string) of property - using square bracket (
[]
): value within[]
should be an expression that evalutes to a string (or sth can convert to string) that contains property name
let author = book.author; // Get the "author" property of the book.
let name = author.surname; // Get the "surname" property of the author.
let title = book["main title"]; // Get the "main title" property of the book.
Create/Set a property:
- Query property, and place it on LHS
book.edition = 7; // Create an "edition" property of book.
book["main title"] = "ECMAScript"; // Change the "main title" property.
6.3.1 Objects As Associative Arrays
object.property // C like structure access
object["property"] // associative array
JS objects are Associative Arrays (e.g. hash or map or dictionary)
- In strong typed language (e.g. C/C++), obj's property are defined. While, JS program can create any number of properties in any object in runtime
.
operator requires name of the property as identifier, which may be unknown in code.[]
operator allow access properties dynamically
Following code shows calculate portfolio value in runtime via associative arrays
function computeValue(portfolio) {
let total = 0.0;
for(let stock in portfolio) { // For each stock in the portfolio:
let shares = portfolio[stock]; // get the number of shares
let price = getQuote(stock); // look up share price
total += shares * price; // add stock value to total value
}
return total; // Return total value.
}