Object对象属性的操作
属性查询
属性查询⼀般有两种⽅法,包括点运算符和⽅括号运算符:
var o = {
p: 'Hello World'
};
o.p // "Hello World"
o['p'] // "Hello World"
1➢点运算
点运算符是很多⾯向对象语句的通⽤写法,由于其⽐较简单,所以较⽅括号运算符相⽐,更常⽤。
当通过点运算符访问对象的属性时,属性名⽤⼀个标识符来表⽰,标识符必须要符合变量命名规则。
标识符必须直接出现在javascript程序中,它们不是数据类型,因此程序⽆法修改它们。
var o = {
a:1,
1:2
};
console.log(o.a);//1
//由于变量不可以以数字开头,所以o.1报错
console.log(o.1);//Uncaught SyntaxError: missing ) after argument list
2➢⽅括号运算
当通过⽅括号运算符来访问对象的属性时,属性名最终通过字符串来表⽰。字符串是javascript的数据类型,在程序运⾏中可以修改和创建它们。使⽤⽅括号运算符有两个优点。
【⼀】可以通过变量来访问属性
var a = 1;
var o = {
1: 10
}
o[a];//10
【⼆】属性名称可以为 javascript⽆效标识符(即,不符合变量命名规则)
var myObject = {
123:'zero',
class:'foo'
};
console.log(myObject['123'],myObject['class']);//'zero' 'foo'
console.log(myObject.123);//报错
2.1➢判断调⽤String()隐式转换
【1】⽅括号中的值若是字符串类型(外⾯有引号),就会正常按字符串访问对象的属性;
【2】⽅括号中的值若是⾮字符串类型(外⾯没有引号),就会先判断是否符合变量命名规则,
【2-1】如果不符合,就会底层调⽤String()隐式转换成字符串再交由⽅括号运算;
【2-2】如果符合,就是变量了,被当作通过变量来访问属性的情况(这个时候,如果对应变量没有定义,当然就会报错)。
2.1.1➢看demo我们就很容易理解:
var myObject = {
123:'this is 123',
clasz:'this is clasz'
};
console.log(myObject["123"]) // 正常访问'this is 123'
console.log(myObject["clasz"]) // 正常访问'this is clasz'
console.log(myObject[123]) // 123隐式转换成字符串"123",访问得到'this is 123'
console.log(myObject[clasz]) // clasz符合变量命名规则,被当作变量:Error: clasz is not defined
2.1.2➢再细看【2-2】:
var myObject = {
123:'this is 123',
clasz:'this is clasz',
extra: 'this is 补充'
};
console.log(myObject[clasz]) // clasz符合变量命名规则,被当作变量:Error: clasz is not defined
对⽐:
var myObject = {
123:'this is 123',
clasz:'this is clasz',
extra: 'this is 补充'
};
var clasz = "extra"
console.log(myObject["clasz"]) // 访问得到'this is 补充'
现在我们就能理解为什么【2】要这么设置了。
2.2➢可计算属性名
在⽅括号运算符内部可以使⽤表达式:
3: 'abc'
};
person[a + 2];//'abc'
但如果要在对象字⾯量内部对属性名使⽤表达式,则需要使⽤ES6的可计算属性名:
var a = 1;
//Uncaught SyntaxError: Unexpected token +
var person = {
a + 3: 'abc'
};
ES6增加了可计算属性名,可以在⽂字中使⽤[]包裹⼀个表达式来当作属性名:
var a = 1;
var person = {
[a + 3]: 'abc'
};
person[4];//'abc'
3➢属性查询错误
【1】查询⼀个不存在的属性不会报错,⽽是返回undefined:
var person = {};
console.log(person.a);//undefined
【2】如果对象不存在,试图查询这个不存在的对象的属性会报错:
console.log(person.a);//Uncaught ReferenceError: person is not defined
可以利⽤这⼀点,来检查⼀个全局变量是否被声明:
/
/ 检查a变量是否被声明
if (a) {...} // 报错
//-----------------------------------------//
//所有全局变量都是window对象的属性。window.a的含义就是读取window对象的a属性,如果该属性不存在,就返回undefined,并不会报错if (window.a) {...} // 不报错
属性设置
属性设置⼜称为属性赋值,与属性查询相同,具有点运算符和⽅括号运算符这两种⽅法。
在给对象设置属性之前,⼀般要先检测对象是否存在:
var len = undefined;
if(book){
if(book.subtitle){
len = book.subtitle.length;
}
}
上⾯代码可以简化为:
var len = book && book.subtitle && book.subtitle.length;
1➢属性设置错误
null和undefined不是对象,给它们设置属性会报错:
null.a = 1;//Uncaught TypeError: Cannot set property 'a' of null
undefined.a = 1;//Uncaught TypeError: Cannot set property 'a' of undefined
由于string、number和boolean有对应的包装对象,所以给它们设置属性不会报错:
'abc'.a = 1;//1
(1).a = 1;//1
true.a = 1;//1
属性删除
使⽤delete运算符可以删除对象属性(包括数组元素):
var o = {
a : 1
};
in运算符的含义console.log(o.a);//1
console.log('a' in o);//true
console.log(delete o.a);//true
console.log(o.a);//undefined
console.log('a' in o);//false
⽽如果给对象属性置null或undefined,其实并没有删除该属性:
var o = {
a : 1
};
o.a = undefined;
console.log(o.a);//undefined
console.log('a' in o);//true
console.log(delete o.a);//true
console.log(o.a);//undefined
console.log('a' in o);//false
使⽤delete删除数组元素时,不会改变数组长度:
var a = [1,2,3];
delete运算符只能删除⾃有属性,不能删除继承属性(要删除继承属性必须从定义这个属性的原型对象上删除它,⽽且这会影响到所有继承⾃这个原型的对象) var o = {
a:1
}
var obj = ate(o);
obj.a = 2;
console.log(obj.a);//2
console.log(delete obj.a);//true
console.log(obj.a);//1
console.log(delete obj.a);//true
console.log(obj.a);//1
1➢返回值
delete操作符的返回值是个布尔值true或false
【1】当使⽤delete操作符删除对象属性或数组元素删除成功时,返回true
var o = {a:1};
var arr = [1];
console.log(delete o.a);//true
console.log(delete arr[0]);//true
【2】当使⽤delete操作符删除不存在的属性或⾮左值时,返回true
var o = {};
console.log(delete o.a);//true
console.log(delete 1);//true
console.log(delete {});//true
【3】当使⽤delete操作符删除变量时,返回false,严格模式下会抛出ReferenceError错误
var a = 1;
console.log(delete a);//false
console.log(a);//1
'use strict';
var a = 1;
//Uncaught SyntaxError: Delete of an unqualified identifier in strict mode
console.log(delete a);
【4】当使⽤delete操作符删除不可配置的属性时,返回false,严格模式下会抛出TypeError错误
var obj = {};
Object.defineProperty(obj,'a',{configurable:false});
console.log(delete obj.a);//false
'use strict';
var obj = {};
Object.defineProperty(obj,'a',{configurable:false});
//Uncaught TypeError: Cannot delete property 'a' of #<Object>
console.log(delete obj.a);
属性继承
每⼀个javascript对象都和另⼀个对象相关联。“另⼀个对象”就是我们熟知的原型,每⼀个对象都从原型继承属性。
对象本⾝具有的属性叫⾃有属性(own property),从原型对象继承⽽来的属性叫继承属性:
var o = {a:1};
var obj = ate(o);
obj.b = 2;
//继承⾃原型对象o的属性a
console.log(obj.a);//1
//⾃有属性b
console.log(obj.b);//2
1➢ hasOwnProperty()
通过hasOwnProperty()⽅法可以确定该属性是⾃有属性还是继承属性
var o = {a:1};
var obj = ate(o);
obj.b = 2;
console.log(obj.hasOwnProperty('a'));//false
console.log(obj.hasOwnProperty('b'));//true
2➢ in
in操作符可以判断属性在不在该对象上,但⽆法区别⾃有还是继承属性:
var o = {a:1};
var obj = ate(o);
obj.b = 2;
console.log('a' in obj);//true
console.log('b' in obj);//true
console.log('b' in o);//false
3➢ for-in
通过for-in循环可以遍历出该对象中所有可枚举属性:
var o = {a:1};
var obj = ate(o);
obj.b = 2;
console.log(obj[i]);//2 1
}
4➢ Object.keys()
Object.keys()⽅法返回所有可枚举的⾃有属性:
var o = {a:1};
var obj = ate(o,{
c:{value:3,configurable: false}
});
obj.b = 2;
console.log(Object.keys(obj));//['b']
5➢ OwnPropertyNames()
与Object.keys()⽅法不同,OwnPropertyNames()⽅法返回所有⾃有属性(包括不可枚举的属性) var o = {a:1};
var obj = ate(o,{
c:{value:3,configurable: false}
});
obj.b = 2;
console.OwnPropertyNames(obj));//['c','b']
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论