一、对象
1、定义:
本质上是一种无序的数据集合,由若干个“键值对”(又称为:成员)(key-value)构成。其中,键值对,包括键名(key,即成员的名称)、键值(value,即成员的值)。
2、先前我们对对象的定义:
1 | object() |
再让我们看看,{}
+键值对所定义的对象,让我们再看一个例子:1
2
3var obj = {
p: 'Hello World'
};
这样看来,相当于1
object() === {}
例子中,{}
定义了一个对象,且被赋值给变量obj。这个对象内部包含一个键值对,P为“键名”,字符串hello world
为“键值”,即:{键名:键值}
,包含多对键值对,每个键值对之间用逗号分隔,如:1
var o = { p1: 'Hello', p2: 'World' };
是不是知道对象是什么了?事实上,{key:value}
这种写法,在JS中我们把它称为JS的对象字面量(也是数组字面量写法)。让我们继续。。。
二、基本使用
首先要定义一个对象
1、对象的一般写法:
1 | var company = { |
或者1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16var company = {
name: '世界你好',
age: 3,
sayHello: function(){
console.log('hello world')
}
}
// undefined
/* 分别调用各属性和值 */
company.name
// "世界你好"
company.age
// 3
company.sayHello()
//hello world
如图:
2、对象里属性值的获取写法:
方法一:1
2
3
4console.log(company.name)
//变量名.属性名 以此来调用值
```
方法二:
console.log(company[‘name’])
//变量名[‘字符串’]1
错误写法:
company[name]
// undefined1
### 3、新增属性,直接赋值
company.addr = ‘杭州市’
//“杭州市”
/ 验证:调用变量,输出:{属性:值} /
company
//{name: “世界你好”, age: 3, sayHello: ƒ, addr: “杭州市”}1
或者
company[‘business’] = ‘学习课程’
//“学习课程”
company
// {name: “世界你好”, age: 3, sayHello: ƒ, addr: “杭州市”, business: “学习课程”}1
2
3
### 4、遍历对象里的属性和值
使用:
for(var 属性名 in 声明的变量){
console.log(key)
console.log(company[key])
}
//key进行遍历时,每一次循环这个变量key,都能调用key里的属性1
2
效果如下:
for(var key in company){
console.log(key)
}
// name
// age
// sayHello
// addr
// business
// undefined1
2
而单个的属性名如何调用:
company[key] === company[‘name’]1
2
3
4
# 三、具体使用
### 1、键名:
(1)键名是字符串(加不加引号都可以)
var o = { ‘p’: ‘Hello World’};1
2
(2)键名是数值,会被自动转为字符串
var o ={
1: ‘a’,
3.2: ‘b’,
1e2: true,
1e-2: true,
.234: true,
0xFF: true
};
o
// Object {
// 1: “a”,
// 3.2: “b”,
// 100: true,
// 0.01: true,
// 0.234: true,
// 255: true
// }1
2
(3)键名不符合标识符条件:第一个字符为数字、含空格和运算符等,必须加上引号(否则报错),如:
var o = {
'1p': "Hello World",
'h w': "Hello World",
'p+q': "Hello World"
};
1 |
|
var o = {
p: function (x)
{
return 2 * x;
}
};
//p为函数
o.p(1)
// 21
2
3
4### 3、多个对象的属性,用逗号分隔(随意加不加)
### 4、属性可以动态创建(不一定在对象声明时就指定)
如:对`obj`对象的`foo`属性赋值,结果就在运行时创建了`foo`属性。
var obj = {};
obj.foo = 123;
obj.foo
// 1231
2
3
4
5
### 5、引用
(1)对象的引用:
A、不同的变量名指向同一个对象,那么它们(变量名)都是这个对象的引用,也就是说指向同一个内存地址。修改其中一个变量,会影响到其他所有变量。o1和o2指向同一个对象,因此为其中任何一个变量添加属性,另一个变量都可以读写该属性。
var o1 = {};
var o2 = o1;
o1.a = 1;
o2.a // 1
o2.b = 2;
o1.b // 21
B、取消某一个变量对于原对象的引用,不会影响到另一个变量。
var o1 = {};
var o2 = o1;
o1 = 1;
o2 // {}1
2
3
4
5
(2)传值引用:不同变量名不对同一对象引用,
第(1)种的引用只限于对象,对原始类型的数据则使用传值引用
当x的值发生变化后,y的值并不变,这就表示y和x并不是指向同一个内存地址。
var x = 1; var y = x; x = 2; y // 11
2
### 6、表达式 ?语句?
{ foo: 123 }1
作为语句,可能是一个代码区块,里面有一个标签`foo`,指向表达式`123`。` === `如果行首是大括号,一律解释为语句(即代码块),如:
/ 假如没有赋值,js引擎默认为块语句 /
{ foo:123 } ==={ label:123}
–>{foo: 123}
->foo: 123
->proto: Object1
作为表达式,可能是一个包含foo属性的对象`===`,如果要解释为表达式(即对象),必须在大括号前加上圆括号,如:
({ foo:123})
//1231
2
3
**题外话:关于eval**
(1)将字符串当做JS语句去执行
eval(‘console.log(123)’)
// 1231
2
3(2)`字符串 === 对象`:
没有`圆括号 ===块语句===代码块` VS `圆括号===表达式===对象`
eval(‘{foo: 123}’)
// 123
eval(‘({foo: 123})’)
// {foo: 123}1
2
3
4
###7、检测变量是否声明(或被定义)
可以在全局作用域中这样检测:
(1)没有声明
‘abc’ in window
// false1
2
(2)有声明
var hello
//undefined
‘hello’ in window
// true1
2
3
4
### 8、查看所有属性
查看对象本身的所有属性,可用`Object.key`或使用`for...in`循环遍历。
(1)方法一:`Object.keys`
var o = {
key1: 1,
key2: 2
};
Object.keys(o);
//(2) [“key1”, “key2”]1
2
(2)方法二:`for...in循环遍历`
var o = {
key1: 1,
key2: 2
};
for(var keys in o){
console.log(keys)
}
// VM4390:6 key1
// VM4390:6 key21
2
3
4
5
6
7
### 9、delete命令
(1)删除一个存在的属性:
两种情况:
**A、只能删除属性**
var o = {p: 1};
Object.keys(o)
// [“p”]
delete o.p ->o.p
Object.keys(o)
// []1
2
3
4
**B、不能删除var命令声明的变量**
var声明的全局变量都是顶层对象的属性,而且默认不得删除。
var p = 1;
delete p // false
delete window.p // false1
2(2)删除一个不存在的属性
delete不报错,而且返回true。不能根据delete命令的结果,认定某个属性是存在的,只能保证读取这个属性肯定得到`undefined`。
var o = {};
delete o.p // true`