概括的讲所有的js对象都是从字符串到值的映射,一个对象中的某一项(键,值对)称作对象的属性。属性的key始终是一个字符串而值可以是任何js值,包括函数。方法是指值为函数的属性。
属性的种类
三种属性:
- 属性(Properties,或称为数据属性) 普通属性,在一个对象里面的一个键值对包括方法,最常用属性。
- 访问器(Accessors,或者叫访问属性) 类似于读写属性的特殊方法。属性值存在普通属性中,而访问属性可以计算他们的值。你可以把他们看作是虚拟的属性,比如(getter 和 setter).
- 内置属性(Internal property) 只存在于ECMAscript规范当中,他们不能被js直接访问,但可以间接的方式访问到。规范里规定将这种属性放在[[]]当中,比如[[Property]]吃有一个对象的原型,它可以通过 Object.getPrototypeOf() 访问到。
对象字面量
JavaScript对象字面量允许你直接的创建简单的对象(Object直接实例)。
例如:
1
2
3
4
5
6
var jane = {
name: 'Jane',
describe: function () {
return 'Person named '+this.name; // (1)
}, // (2)
};
- 使用this来指代当前对象.
- ECMAScript 5 允许最后一个属性跟一个逗号,但不是所有的旧版本浏览器都支持这个做法.这个逗号还是挺管用的, 你可以重排属性而不用担心谁在最后.
你可能有这样的印象,对象仅仅是字符串到值的映射。事实上远不止这些,有一些真正意义上的通用对象。
比如你可以做对象的继承,还可以保护对象不被修改。直接创建对象的功能是标准的js特性之一:你可以在没有类的前提下创建一个正确的对象,然后再对他进行抽象。
例如:构造函数(constructors)大体和其他语言的类相似,我们在后面会降到。
点运算符 (.): 通过固定值来访问属性
点运算符提供了一种简洁的语法来访问属性,属性的名称必须是合法标识符. 你可以用中括号来读写任意名称的属性.
1 | var jane = { |
获取属性
点操作符获取属性 (读值).例如:
1 | > jane.name // get property `name` |
如果属性不存在则返回 undefined
:
1 | > jane.unknownProperty |
调用方法
也可以调用方法:
1 | > jane.describe() // call method `describe` |
设置属性
可以用赋值符=
来给.
指向的属性赋值:
1 | > jane.name = 'John'; // set property `name` |
如果设置的属性不存在在赋值的时候就自动创建一个属性.如果存在就修改该属性。
删除属性
delete
操作符可以完全的从对象里面删除一个属性(键值对):
1 | > var obj = { hello: 'world' }; |
如果你仅仅给一个属性设置为undefined,这个属性会仍然存在,而且这个对象包含这个键:
1 | > var obj = { foo: 'a', bar: 'b' }; |
但是如果你将属性删除那么他的键就不存在了
1 | > delete obj.foo |
delete
只影响一个对象的直接属性(非继承的,自有属性)。并不会删除对象的原型。
Tip
慎用delete操作符,大多数现代化js引擎都会针对构造函数的创建实例进行优化,前提是这些实例不会发生形态改变(就是说没有删除或者添加属性的),但是删除属性会破坏这种优化。
delete的返回值
如果属性是一个自有属性且不能删除,那么delete
会反回false,其他情况返回true。
例子:
作为准备,我们用Object.defineProperty创建一个不被删除自有属性1
2
3
4
5
6
7
8
9var obj = {};
Object.defineProperty(obj, 'canBeDeleted', {
value: 123,
configurable: true
});
Object.defineProperty(obj, 'cannotBeDeleted', {
value: 456,
configurable: false
});
delete
cannotBeDeleted 时候返回 false
:
1 | > delete obj.cannotBeDeleted |
其他情况下delete
返回 true
:
1 | > delete obj.doesNotExist |
即使delete
没有起作用也会返回true
(继承的属性是不会被移除的):
1 | > delete obj.toString |
特殊属性键
虽然你不能使用保留字作为变量名,但是你可以把他们作为属性键。
1 | > var obj = { var: 'a', function: 'b' }; |
数字也可以作为属性键,但会被解析成字符串。点操作符不能访问他们(只能访问键为标识符的属性)所以要用[]
来访问:
1 | > var obj = { 0.7: 'abc' }; |
对象字面量,同样允许你使用其他任意字符串来做为键,但是你必须用上单引号,且需要用[]
来访问。
1 | > var obj = { 'not an identifier': 123 }; |
中括号 ([]): 通过计算出来的键访问属性
中括号可以通过表达式引用一个属性。
用中括号获取属性:
1 | > var obj = { someProperty: 'abc' }; |
非标识符:
1 | > var obj = { 'not an identifier': 123 }; |
表达式,转换成字符串:
1 | > var obj = { '6': 'bar' }; |
用中括号调用方法
1 | > var obj = { myMethod: function () { return true } }; |
用中括号设置属性
1 | > var obj = {}; |
用中括号删除属性
1 | > var obj = { 'not an identifier': 1, prop: 2 }; |