下面关于对象
1、对象就是一组“键值对”(key-value)的集合,是一种无序的复合数据集合。
var obj = {
foo: 'Hello',
bar: 'World'
};
对象的所有键名都是字符串(ES6 又引入了 Symbol 值也可以作为键值),所以加不加引号都可以。上面的代码也可以写成下面这样。
var obj = {
'foo': 'Hello',
'bar': 'World'
};
正常情况下,键名可以是带引号或者不带引号,就算不带引号,程序也能自动把它识别成字符串,但是一些特殊的键名是不能识别的,所以要带引号。如果键名不符合标识名的条件(比如第一个字符为数字,或者含有空格或运算符),且也不是数字,则必须加上引号,否则会报错。比如:
// 报错
var obj = {
1p: 'Hello World'
};
// 不报错
var obj = {
'1p': 'Hello World',
'h w': 'Hello World',
'p+q': 'Hello World'
};
2、
{ foo: 123 }
上面代码会出现一个问题:如果行首是一个大括号,它里边是个对象,它到底是表达式还是语句?
JavaScript 引擎读到上面这行代码,会发现可能有两种含义。第一种可能是,这是一个表达式,表示一个包含foo属性的对象;第二种可能是,这是一个语句,表示一个代码区块,里面有一个标签foo,指向表达式123。
为了避免这种歧义,JavaScript 规定,如果行首是大括号,一律解释为语句(即代码块)。如果要解释为表达式(即对象),必须在大括号前加上圆括号。
({ foo: 123})
这样用evel()语句上表现的更为明显。
我们都知道把一个对象转换为对象字符串可以用JSON.stringify() ,或者用evel(),但是用evel的时候我们要在对象外边再加一层小括号,否则就不能得到我们想要的对象字符串,这是为什么呢,原因就是上述说的。如下:
eval('{foo: 123}') // 123
eval('({foo: 123})') // {foo: 123}
如果没有圆括号,eval将其理解为一个代码块;加上圆括号以后,就理解成一个对象。
关于属性的操作
采用点运算符和方括号运算符,都可以读取属性。但是使用方括号运算符,键名必须放在引号里面,否则会被当作变量处理。如下:
var foo = 'bar';
var obj = {
foo: 1,
bar: 2
};
obj.foo // 1
obj.["foo"] // 1
obj[foo] // 2
数字键可以不加引号,因为会自动转成字符串。
var obj = {
0.7: 'Hello World'
};
obj['0.7'] // "Hello World"
obj[0.7] // "Hello World"
对象obj的数字键0.7,加不加引号都可以,因为会被自动转为字符串。
注意,数值键名不能使用点运算符(因为会被当成小数点),只能使用方括号运算符。
var obj = {
123: 'hello world'
};
obj.123 // 报错
obj[123] // "hello world"
铛铛铛,划重点了!!!!
查看一个对象的所有属性的方法——-Object.keys(obj)
var obj = {
key1: 1,
key2: 2
};
Object.keys(obj);
// ['key1', 'key2']
删除一个对象的属性的方法——-delete obj.p
var obj = { p: 1 };
Object.keys(obj) // ["p"]
delete obj.p // true
obj.p // undefined
Object.keys(obj) // []
对象obj并没有p属性,但是delete命令照样返回true。
var obj = {};
delete obj.p // true
只有一种情况,delete命令会返回false,那就是该属性存在,且不得删除。
var obj = Object.defineProperty({}, 'p', {
value: 123,
configurable: false
});
obj.p // 123
delete obj.p // false
delete命令只能删除对象本身的属性,无法删除继承的属性
var obj = {};
delete obj.p // true
obj.p // function p() { [native code] }
实用的in方法
检查对象中是否包含某个属性,可以直接通过in检测,如果返回true则说明obj包含某个属性,否则不包含。如:
var obj = {p: 3}
'p' in obj //true
但是它不能识别哪个是自身的,哪个是继承的!!!
'a' in obj //true 此时a是继承的属性
for ….in….方法
提取对象的属性名现在就有两种方法了
第一种:
var obj = {
x: 1,
y: 2
};
var props = [];
var i = 0;
for (var p in obj) {
props[i++] = p
}
props // ['x', 'y']
第二种:
var obj = {
x: 1,
y: 2
};
Object.keys(obj) // ['x','y']
如果继承的属性是可遍历的,那么就会被for…in循环遍历到。但是,一般情况下,都是只想遍历对象自身的属性,所以使用for…in的时候,应该结合使用hasOwnProperty方法,在循环内部判断一下,某个属性是否为对象自身的属性。
var person = { name: '老张' };
for (var key in person) {
if (person.hasOwnProperty(key)) {
console.log(key);
}
}
// name
对象的with方法
格式如下,它的作用是操作同一个对象的多个属性时,提供一些书写的方便。
with (对象) {
语句;
}
例:
// 例一
var obj = {
p1: 1,
p2: 2,
};
with (obj) {
p1 = 4;
p2 = 5;
}
// 等同于
obj.p1 = 4;
obj.p2 = 5;
// 例二
with (document.links[0]){
console.log(href);
console.log(title);
console.log(style);
}
// 等同于
console.log(document.links[0].href);
console.log(document.links[0].title);
console.log(document.links[0].style);
注意,如果with区块内部有变量的赋值操作,必须是当前对象已经存在的属性,否则会创造一个当前作用域的全局变量。
var obj = {};
with (obj) {
p1 = 4;
p2 = 5;
}
obj.p1 // undefined
p1 // 4
with方法有一些弊端,所以实际操作中不建议使用,可以简单做一下了解。