对象

原文地址:https://wangdoc.com/javascript/

概述

简单的说,对象就是一组键值对的集合。

键名

对象的所有键名都是字符串(ES6又引入了Symbol值也可以作为键名),所以加不加引号都可以。但是如果键名不符合标识符的条件,必须要加上引号,否则会报错。属性值还可以是对象,就形成了链式引用。

var object1 = {};
var object2 = {bar : "hello"};
object1.foo = object2;
object1.foo.bar // "hello"

上面的代码直接对object2对象的foo属性赋值,结果就在运行时创建了foo属性。

对象的引用

如果不同的变量指向同一个对象,那么它们都是这个对象的引用,也就是说指向了同一块内存。修改其中一个变量,会影响到其他的所有变量,如果取消一个变量对原对象的引用,不会影响到其他的变量。

var object1 = {};
var object2 = object1;

object1.a = 1;
object2.a // 1

object1 = 1;
object2 // {}

但是这种引用只局限于对象,如果两个变量指向同一个原始类型的值。那么,变量是值得拷贝。

var x = 1;
var y = x;

x = 2;
y // 1

表达式还是语句

对象采用大括号表示,这就导致了一个问题,如果行首是一个大括号,它到底是表达式还是语句?

{ foo: 123 }

JavaScript引擎读到上面的这行代码,会发现可能有两种含义。

  • 这是一个表达式,表示一个包含foo属性的对象;
  • 这是一个代码块,label为foo,指向表达式123。
    为了避免这种歧义,V8引擎规定,如果行首是大括号,一律解释为对象。不过为了避免歧义,最好加上小括号。这种差异在eval语句中反应的最为明显。
({ foo: 123 })
eval("{foo: 123}") // 123 代码块
eval("({foo: 123})") // {foo: 123} 对象

属性的操作

属性的访问

有两种方式

  • 点运算符
  • 方括号运算符
var obj = {
    p: "Hello World!"
};
obj.p // "Hello World!"
obj["p"] // "Hello World!"

注意使用方括号运算符时,属性名必须加引号,否则会当做变量处理

var foo = "bar";
var obj = {
    foo: 1,
    bar: 2
};

obj.foo // 1
obj.[foo] // 2

方括号运算符内部可以使用表达式,纯数字键可以不加引号,会自动转成字符串,但是纯数字键名不能使用点运算符,只能使用方括号运算符

obj["hello" + "world"]
var obj2 = {
    0.7: "hello"
}
obj2[0.7] // "hello"
obj2["0.7"] // "hello"

属性的赋值

点运算符和方括号运算符不仅可以用来访问,还可以用来赋值。
JavaScript允许属性的后绑定,也就是说,你可以在任意时刻新增属性,没必要在定义对象的时候,就定义好属性。

var obj = { p : 1};
// 等价于
var obj = {};
obj.p = 1;
### 属性的查看
查看一个对象所有的属性,可以使用<font color=red>Object.keys()</font>方法。

var obj = {
key1: 1,
key2: 2
};
Object.keys(obj); // ["key1", "key2"]
### 属性的删除:delete关键字 <font color=red>delete</font>关键字用于删除对象的属性,删除成功后返回<font color=red>true</font>。**注意,删除一个不存在的属性,<font color=red>delete</font>不报错,而且返回<font color=red>true</font>,只有一种情况,<font color=red>delete</font>会返回false,那就是这个属性存在,且不能删除。js
var obj = { p: 1 };
Object.keys(obj); // ["p"]
delete obj.p; // true
obj.p // undefined
Object.keys(obj); // []
delete obj.o // true

var obj = Object.defineProperty({}, "p", {
value: 123,
configurable: false
});
obj.p // 123
delete obj.p // false
另外,需要注意的是,<font color=red>delete</font>只能删除对象本身的属性,无法删除继承的属性。js
var obj = {};
delete obj.toString // true
obj.toString // function toString() { [native code] }
上面代码中,<font color=red>toString</font>是<font color=red>obj</font>继承的属性,虽然返回<font color=red>true</font>,但该属性并没有被删除。说明**即使<font color=red>delete</font>返回<font color=red>true</font>,该属性依然可能读到值。 ### 属性是否存在:in预算符 <font color=red>in</font>运算符用于检查对象是否包含某个属性,包含返回<font color=red>true</font>,否则返回<font color=red>false</font>。<font color=red>in</font>运算符的一个问题是,它不能识别哪些属性是自身的,哪些是继承的。这时,可以用对象的<font color=red>hasOwnProperty</font>方法判断一下。js
var obj = {p: 1};
"p" in obj // true
"toString" in obj // true

if ("toString" in obj) {
console.log(obj.hasOwnProperty("toString")) // false
}
### 属性的遍历: for ... in循环js
var obj = {a: 1, b: 2, c: 3};

for (var i in obj) {
console.log("key: " + i);
console.log("value: " + obj[i]); // 注意是obj[i]
}
注意点:

  • 它遍历的是所有可遍历的属性,会跳过不可遍历的属性
  • 它不仅遍历对象自身的属性,还遍历继承的属性
    举例来说,对象都继承了toString属性,但是for...in循环不会遍历这个属性。
    一般情况下,都是只想遍历自身的属性,所以使用for...in的时候,应该结合使用hasOwnProperty方法。
var person = {...}
for (var key in person) {
    if (person.hasOwnProperty(key)) {
        console.log(key);
    }
}

with语句

with语句格式如下

with (对象) {}
    语句;
}
它的作用是操作同一个对象的多个属性时,提供一些书写的方便。

var obj = {
p1: 1,
p2: 2,
};
with (obj) {
p1 = 4;
p2 = 5;
}
// 等同于
obj.p1 = 4;
obj.p2 = 5;
注意,**如果<font color=red>with</font>区块内部有变量的赋值操作,必须是当前对象已经存在的属性,否则会创造一个当前作用域的全局变量。js
var obj = {};
with (obj) {
p1 = 4;
}
obj.p1 // undefined
p1 // 4

**这是因为<font color=red>with</font>区块没有改变作用域,它的内部依然是当前作用域。这造成<font color=red>with</font>语句一个很大的弊病,就是绑定对象不明确**。

with (obj) {
console.log(x);
}

单纯从上面的代码块,根本无法判断<font color=red>x</font>到底是全局变量,还是对象<font color=red>obj</font>的一个属性。**建议不要使用<font color=red>with</font>语句,可以考虑用一个临时变量代替**。

with (obj1.obj2.obj3) {
console.log(p1 + p2);
}
// 写成
var temp = obj1.obj2.obj3;
console.log(temp.p1 + temp.p2);
```

转载于:https://www.cnblogs.com/chris-jichen/p/9930079.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值