Objects can be initialized using
new Object()
,
Object.create()
, or using the
literal
notation (
initializer
notation). An object initializer is a comma-delimited list of zero or more pairs of property names and associated values of an object, enclosed in curly braces (
{}
).
The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.
let o = {}
let o = {a: 'foo', b: 42, c: {}}
let a = 'foo', b = 42, c = {}
let o = {a: a, b: b, c: c}
let o = {
property: function (parameters) {},
get property() {},
set property(value) {}
};
Please see the compatibility table for support for these notations. In non-supporting environments, these notations will lead to syntax errors.
// Shorthand property names (ES2015)
let a = 'foo', b = 42, c = {};
let o = {a, b, c}
// Shorthand method names (ES2015)
let o = {
property(parameters) {}
}
// Computed property names (ES2015)
let prop = 'foo'
let o = {
[prop]: 'hey',
['b' + 'ar']: 'there'
}
An object initializer is an expression that describes the initialization of an
Object
. Objects consist of
properties
, which are used to describe an object. Values of object properties can either contain
primitive
data types or other objects.
The object literal notation is not the same as the J ava S cript O bject N otation ( JSON ). Although they look similar, there are differences between them:
"property": value
syntax. The property name must be double-quoted, and the definition cannot be a shorthand.
true
,
false
,
null
, or another (JSON) object.
Date
will be a string after
JSON.parse()
.
JSON.parse()
will reject computed property names and an error will be thrown.
An empty object with no properties can be created like this:
let object = {}
However, the advantage of the
literal
or
initializer
notation is, that you are able to quickly create objects with properties inside the curly braces. You simply notate a list of
key: value
pairs delimited by commas.
The following code creates an object with three properties and the keys are
"foo"
,
"age"
and
"baz"
. The values of these keys are a string
"bar"
, the number
42
, and another object.
let object = {
foo: 'bar',
age: 42,
baz: {myProp: 12}
}
Once you have created an object, you might want to read or change them. Object properties can be accessed by using the dot notation or the bracket notation. (See property accessors for detailed information.)
object.foo // "bar" object['age'] // 42 object.foo = 'baz'
We have already learned how to notate properties using the initializer syntax. Oftentimes, there are variables in your code that you would like to put into an object. You will see code like this:
let a = 'foo',
b = 42,
c = {};
let o = {
a: a,
b: b,
c: c
}
With ECMAScript 2015, there is a shorter notation available to achieve the same:
let a = 'foo',
b = 42,
c = {};
// Shorthand property names (ES2015)
let o = {a, b, c}
// In other words,
console.log((o.a === {a}.a)) // true
When using the same name for your properties, the second property will overwrite the first.
let a = {x: 1, x: 2}
console.log(a) // {x: 2}
In ECMAScript 5 strict mode code, duplicate property names were considered a
SyntaxError
. With the introduction of computed property names making duplication possible at runtime, ECMAScript 2015 has removed this restriction.
function haveES2015DuplicatePropertySemantics() {
'use strict';
try {
({prop: 1, prop: 2});
// No error thrown, duplicate property names allowed in strict mode
return true;
} catch(e) {
// Error thrown, duplicates prohibited in strict mode
return false;
}
}
A property of an object can also refer to a function 或 getter or setter 方法。
let o = {
property: function (parameters) {},
get property() {},
set property(value) {}
}
In ECMAScript 2015, a shorthand notation is available, so that the keyword "
function
" is no longer necessary.
// Shorthand method names (ES2015)
let o = {
property(parameters) {},
}
In ECMAScript 2015, there is a way to concisely define properties whose values are generator functions:
let o = {
*generator() {
...........
}
};
Which is equivalent to this ES5-like notation (but note that ECMAScript 5 has no generators):
let o = {
generator: function* () {
...........
}
};
For more information and examples about methods, see method definitions .
Starting with ECMAScript 2015, the object initializer syntax also supports computed property names. That allows you to put an expression in brackets
[]
, that will be computed and used as the property name. This is reminiscent of the bracket notation of the
property accessor
syntax, which you may have used to read and set properties already.
Now you can use a similar syntax in object literals, too:
// Computed property names (ES2015)
let i = 0
let a = {
['foo' + ++i]: i,
['foo' + ++i]: i,
['foo' + ++i]: i
}
console.log(a.foo1) // 1
console.log(a.foo2) // 2
console.log(a.foo3) // 3
let param = 'size'
let config = {
[param]: 12,
['mobile' + param.charAt(0).toUpperCase() + param.slice(1)]: 4
}
console.log(config) // {size: 12, mobileSize: 4}
Rest/Spread Properties for ECMAScript proposal (stage 4) adds spread properties to object literals. It copies own enumerable properties from a provided object onto a new object.
Shallow-cloning (excluding
prototype
) or merging objects is now possible using a shorter syntax than
Object.assign()
.
let obj1 = { foo: 'bar', x: 42 }
let obj2 = { foo: 'baz', y: 13 }
let clonedObj = { ...obj1 }
// Object { foo: "bar", x: 42 }
let mergedObj = { ...obj1, ...obj2 }
// Object { foo: "baz", x: 42, y: 13 }
注意,
Object.assign()
triggers
setters
, whereas the spread operator doesn't!
A property definition of the form
__proto__: value
or
"__proto__": value
does not create a property with the name
__proto__
. Instead, if the provided value is an object or
null
, it changes the
[[Prototype]]
of the created object to that value. (If the value is not an object or
null
, the object is not changed.)
let obj1 = {}
assert(Object.getPrototypeOf(obj1) === Object.prototype)
let obj2 = {__proto__: null}
assert(Object.getPrototypeOf(obj2) === null)
let protoObj = {}
let obj3 = {'__proto__': protoObj}
assert(Object.getPrototypeOf(obj3) === protoObj)
let obj4 = {__proto__: 'not an object or null'}
assert(Object.getPrototypeOf(obj4) === Object.prototype)
assert(!obj4.hasOwnProperty('__proto__'))
Only a single prototype mutation is permitted in an object literal. Multiple prototype mutations are a syntax error.
Property definitions that do not use "colon" notation are not prototype mutations. They are property definitions that behave identically to similar definitions using any other name.
let __proto__ = 'variable'
let obj1 = {__proto__}
assert(Object.getPrototypeOf(obj1) === Object.prototype)
assert(obj1.hasOwnProperty('__proto__'))
assert(obj1.__proto__ === 'variable')
let obj2 = {__proto__() { return 'hello'; }}
assert(obj2.__proto__() === 'hello')
let obj3 = {['__prot' + 'o__']: 17}
assert(obj3.__proto__ === 17)
| 规范 |
|---|
|
ECMAScript (ECMA-262)
The definition of 'Object Initializer' in that specification. |
| Desktop | Mobile | Server | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 对象初始化器 | Chrome 1 | Edge 12 | Firefox 1 | IE 1 | Opera 4 | Safari 1 | WebView Android 1 | Chrome Android 18 | Firefox Android 4 | Opera Android 10.1 | Safari iOS 1 | Samsung Internet Android 1.0 | nodejs 0.1.100 |
| Computed property names | Chrome 47 | Edge 12 | Firefox 34 | IE No | Opera 34 | Safari 8 | WebView Android 47 | Chrome Android 47 | Firefox Android 34 | Opera Android 34 | Safari iOS 8 | Samsung Internet Android 5.0 | nodejs 4.0.0 |
| Shorthand method names | Chrome 47 | Edge 12 | Firefox 34 | IE No | Opera 34 | Safari 9 | WebView Android 47 | Chrome Android 47 | Firefox Android 34 | Opera Android 34 | Safari iOS 9 | Samsung Internet Android 5.0 | nodejs 4.0.0 |
| Shorthand property names | Chrome 47 | Edge 12 | Firefox 33 | IE No | Opera 34 | Safari 9 | WebView Android 47 | Chrome Android 47 | Firefox Android 33 | Opera Android 34 | Safari iOS 9 | Samsung Internet Android 5.0 | nodejs 4.0.0 |
| Spread properties | Chrome 60 | Edge 79 | Firefox 55 | IE No | Opera 47 | Safari 11.1 | WebView Android 60 | Chrome Android 60 | Firefox Android 55 | Opera Android 44 | Safari iOS 11.3 | Samsung Internet Android 8.0 | nodejs 8.3.0 |
完整支持
不支持
实验。期望将来行为有所改变。