-
Notifications
You must be signed in to change notification settings - Fork 4
Objects
◄ Back (Functions)
Next (The Module Pattern) ►
- Objects
- Objects and Primitive Data Types
- instanceof
- Constructor functions that return objects
- Objects are passed by reference, not by value
JavaScript is an object-oriented language, but objects in JavaScript work quite differently than they do in other languages?
In JavaScript, an object is a collection of properties. Every property in a JavaScript object has a key that can be represented by a string, and that key is unique. You cannot have two properties with the same key. The key is used to retrieve the value of a given property:
var dog = {
breed: 'Golden Retriever', // we can either specify the key without quotes,
// in which case we can access the property using
// dot or bracket notation. If we specify the property
// as a string with spaces in it than
// bracket notation must be used
name: 'Cody'
};
console.log(dog.name); // prints Cody
console.log(dog['name']); // also prints Cody
Creating objects in this way is called using an object initializer and the syntax is known as using object literal notation. The exact syntax is:
var obj = {
property1: value_1, // property_# may be an identifier...
2: value_2, // or a number... must be accessed with brackets obj[2]
// ..., more properties here
'property n': value_n }; // or a string... must be accessed with brackets obj['property n']
where obj is the name of the new object, each property is an identifier (either a name, a number, or a string literal), and each value is an expression whose value is assigned to the property. For more on objects, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects
You can use dot or bracket notation to get or set the value of an object's property. You can use these almost interchangably. In the case where you want to resolve some value to a string in order to access a property rather than using the name of that property directly, you need to use bracket notation. The same goes for properties that are represented by strings with spaces in them (or any character other than letters, numbers, $, _ and a few others)[1]:
var holderForPropertyName = 'name';
dog.name = 'Repl';
console.log(dog.name); // prints Repl
dog['name'] = 'Knuthy';
console.log(dog['name']); // prints Knuthy
console.log(dog[holderForPropertyName]); // also prints Knuthy
console.log(dog.name); // also prints Knuthy
// the following is valid but there is no way to use dot notation with it
dog['favorite expression'] = 'bark'; // this is valid
console.log(dog['favorite expression']); // prints dog
/**
* BUT THIS WILL NOT WORK
* console.log(dog.holderForPropertyName); // no good
* You can't use dot notation to resolve the value of a variable
* to a property name
*/
You can delete an object property using the delete keyword:
delete dog.name; // this removes this property from the object
// you won't need this all that often
console.log(dog.name); // prints undefined
As we mentioned, there are 5 primitive data types in JavaScript:
- Boolean
- Null
- Undefined
- Number
- String
- Symbol (new in ECMAScript 6, which will make 6)
These primitive types define immutable values. They cannot be changed. When you change a String, for example, a new String is created. All of these primitive types have equivalent representations as objects, and indeed JavaScript will automatically convert between the two so you can get the benefits of both without having to concern yourself with the details. Because these primitives can be converted to objects automatically, they effectively have methods on them that you can call directly. When you say var stringPrimitive = 'this is a string';
, 'this is a string' is a String literal. To create a String object you could then say var stringObject = new String(stringPrimitive);
and you will have an String object. But you don't need to do this. When you say 'this is a string'.indexOf('t');
, JavaScript will convert the String literal into an object and call the indexOf method that is on that String object's prototype, along you to call indexOf directly without having to think about it. The end result is, Number, Boolean, String, Array, Date, RegExp, and Function are all objects in JavaScript.
Objects can inherit directly from other objects.
Technically, starting with JavaScript 1.5, these are the legal characters for an identifier:
A JavaScript identifier must start with a letter, underscore (_), or dollar sign ($); subsequent characters can also be digits (0-9). Because JavaScript is case sensitive, letters include the characters "A" through "Z" (uppercase) and the characters "a" through "z" (lowercase).
Starting with JavaScript 1.5, you can use ISO 8859-1 or Unicode letters such as å and ü in identifiers. You can also use the \uXXXX Unicode escape sequences as characters in identifiers.
See the Values, variables, and literals MDN documentation
In Object-Oriented JavaScript, the author says that the instanceof operator is used to test if an object was created with a specific constructor function, and that:
function Calculator() {}
var calc = new Calculator();
var o = {};
calc instanceof Calculator; // true
calc instanceof Object; // false
typeof calc; // 'object'
o instanceof Object; // true
This is not the case. The instanceof operator tests whether an object has the prototype property of a given constructor anywhere in its prototype chain:
function Calculator() {}
var calc = new Calculator();
var o = {};
calc instanceof Calculator; // true
// THIS WILL BE TRUE because Object is in calc's prototype chain
calc instanceof Object; // true
typeof calc; // 'object'
o instanceof Object; // true
function ValueHolder(a, b) {
this.valueA = a;
return {
valueB: b
};
}
var holder = new ValueHolder('pigeons', 'dolphins');
console.log(typeof holder.valueA); // undefined, pigeons are gone!
console.log(holder.valueB); // dolphins
When you return an object from a function, the default behavior of the constructor function is ignored and only that object is returned. When this is the case, there is no reason to use the new keyword, since simply calling the function will return the very same thing.
When you assign an object to a variable or pass it to a function, you are only passing a reference to the object:
var surveyData = {
yeses: 23,
nos: 0
};
var dataCopy = surveyData; // this is still just surveyData!
dataCopy.yeses; // 23
surveyData.yeses; // 23
dataCopy.yeses = 0;
dataCopy.yeses; // 0
surveyData.yeses; // 0 uh-oh, we just changed the original too