JavaScript 对象类型详解笔记
XMit Lv3

JavaScript 的数据类型

  • 引用类型(即 Object 类型)
  • 基本类型(原始类型)
    • Number
    • String
    • Boolean
    • Undefined
    • Null

什么是对象

对象是属性的无序集合,每个属性都是一个名/值对。这个列表中的每一项被称为属性(如果是函数则被称为方法)。
一个简单的对象:

1
2
3
4
var Person = {
name: 'xiaowang',
age: 28
}

上例中的属性名是name、age,相对应的值是xianwang、28

引用数据类型和原始数据类型两者的区别

引用类型的值是按引用访问的,而原始类型按值访问的。
原始类类型复制变量值:

1
2
3
4
5
var num1 =5;
var num2 = num1;
num1 = 9;
console.log(num1); // 9
console.log(num2); // 5

引用类型复制变量值:

1
2
3
4
5
6
var obj1 = new Object();
obj1.name = 'xiaowang';
var obj1 = obj2;
obj1.name = 'xiaoming';
console.log(obj1.name); // xiaoming
console.log(obj2.name); // xiaoming

上面这个例子中,当一个变量向另一个变量复制引用值时,由于变量对象中存储的是引用,所以这个值的副本实际上是一个指针,指向存储在堆中的一个对象。复制操作结束后,两个变量实际将引用同一个对象,因此,改变其中一个变量,就会影响另一个变量。

对象属性的特性

数据属性:

  • Configurable : 指定这个对象的属性是否可以被删除或修改。
  • Enumerable : 指定这个对象的属性能否通过 for - in 循环取得。
  • Writable : 指定这个对象属性是否可以被修改。
  • Value : 指定这个对象的属性值。默认是Undefined

修改对象属性特性的方法:Object.defineProperty()
参数:

  • 属性所在的对象
  • 属性的名字
  • 描述符(必须是Configurable、Enumerable、Writable等中一个或者多个)

创建对象

创建对象的两种常用方法:
对象字面量:直接使用頞量进行创建

1
2
3
4
5
6
7
8
var Person = {
name: 'xiaowang',
age: 28,

sayAge:function() {
console.log(this.age);
}
}

对象构造函数:使用new关键字来调用构造函数

1
2
3
4
5
6
7
var Person = new Object();
Person.name = 'xiaowang';
Person.age = 28;

Person.sayAge = function() {
console.log(this.age);
}

对象创建实践

用程序展示水果和安的详细信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var mangoFruit = {
color: 'yellow',
sweetness: 8,
fruitName : 'Mango',
nativeToLand: ["South America", "Central America"],

showName: function() {
console.log('This is ' + this.fruitName);
},
native: function() {
this.nativeToLand.forEach(function(eachCountry){
console.log('Grow in:' + eachCountry);
})
}
}
mangoFruit.native();

// Grow in:South America
// Grow in:Central America

以上例子有个明显的问题,如果有多个水果,就得添加多次相同的代码。
为了解决多个相似对象的问题,下面是两种创建对象的常用模式:

构造方法模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function Fruit(theColor, theSweetness, theFruitName, theNativeToLand){
this.color = theColor,
this.sweetness = theSweetness,
this.fruitName = theFruitName,
this.nativeToLand= theNativeToLand,

this.showName = function() {
console.log('This is ' + this.fruitName);
},
this.nativeTo = function() {
this.nativeToLand.forEach(function(a){
console.log('Grow in:' + a);
})
}
}
var mangoFruit = new Fruit ("Yellow", 8, "Mango", ["South America", "Central America", "West Africa"]);
mangoFruit.nativeTo();

// Grow in:South America
// Grow in:Central America
// Grow in:West Africa

原型模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function Fruit () {
}

Fruit.prototype.color = "Yellow";
Fruit.prototype.sweetness = 7;
Fruit.prototype.fruitName = "Generic Fruit";
Fruit.prototype.nativeToLand = "USA";

Fruit.prototype.showName = function () {
console.log("This is a " + this.fruitName);
}

Fruit.prototype.nativeTo = function () {
console.log("Grown in:" + this.nativeToLand);
}

var mangoFruit = new Fruit ();
mangoFruit.showName();
mangoFruit.nativeTo();

// This is a Generic Fruit
// Grown in:USA

访问对象中的属性

访问对象属性的两种主要方法是点记法和中括号记法。
点记号

1
2
3
4
5
var Person = {
name: 'xiaowang',
age: 28
}
console.log(Person.name); // xiaowang

中括号记

1
2
3
4
5
var Person = {
name: 'xiaowang',
age: 28
}
console.log(Person["name"]); // xiaowang

自身属性和继承属性

对象拥有自身属性和继承属性。自身属性是直接定义在对象上的属性,而继承属性是从Object的Prototype继承的属性。

为了确写一个对象是否拥有某个属性(不管是自身属性还是继承属性),可以使用in操作符

1
2
3
4
5
6
7
8
9
10
var Person = {
name: 'xiaowang',
age: 28
}
// 自身属性
console.log('name' in Person); // true
// 继承属性
console.log('toString' in Person); // true
// 不存在的属性
console.log('gg' in Person); // false

为了确定一个对象是否拥有一个特定的自身属性,可以使用hasOwnProperty方法

1
2
3
4
5
6
7
8
var Person = {
name: 'xiaowang',
age: 28
}
// 自身属性
console.log(Person.hasOwnProperty('name')); // true
// 继承属性
console.log(Person.hasOwnProperty("toString")); // false

访问和枚举对象的属性

1
2
3
4
5
6
7
var Person = {
name: 'xiaowang',
age: 28
}
for(var key in Person) {
console.log(key); // name age
}

访问继承的属性

1
2
3
4
5
6
7
8
9
10
11
function Person() {
this.name = 'xiaowang';
}

var Person1 = new Person();
Person1.height = 123;
Person1.width = 345;

for(var key in Person1) {
console.log(key); // name height widht
}

删除对象中的属性

可以使用delete操作符来删除对象中的属性。我们不能删除继承的属性,同时也不能删除Configurable特性被设置为false的对象属性。要删除继承的属性,必须从Prototype对象中删除(也就是定义这些属性的地方)。并且,我们也不能删除全局对象中的属性。

删除成功的时候,delete操作符会返回true。令人意外的是,当要删除的属性不存在,或者不能被删除(即不是自身的属性或者Configurable特性被设置为false)时, delete操作符也会返回true。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
var Person = {
name: 'xiaowang',
age: 28
}
delete Person.name; // 删除自带属性

for (var key in Person) {
console.log(key); // age
}

delete Person.toString; // true 因为toString是继承的属性,所以它不会被删除
console.log(Person.toString); // 能正常使用,因为继承的属性无法删除

// 如果一个属性是对象实例的自身属性,则我们可以删除它。
function Person() {
this.name = 'xiaowang';
}

var Person1 = new Person();
Person1.height = 123;
Person1.width = 345;

console.log(Person1.hasOwnProperty("name")); // true

// 删除自身属性
delete Person1.name; // true
console.log(Person1.name);// undefined

// 但是name属性仍然存在于Person函数中
var Person2 = new Person ();
console.log(Person2.name); // xiaowang

// 在Person函数prototype中定义了一个属性
Person.prototype.age = 29;

console.log(Person1.hasOwnProperty('age')); // false
console.log(Person1.age); // 29

// 尝试删除继承的age属性
delete Person1.age; // true
console.log(Person1.age); // 29

序列化和反序列化对象

为了在HTTP中传递对象或者将对象转化成字符串,我们必须将对象序列化(将其转化为字符串)。我们可以使用JSON.stringify来序列化对象。要注意的是,在ECMAScript 5之前的版本,我们要使用json2库来获得JSON.stringify函数。在ECMAScript 5中,这个函数已经成为标准函数。

为了将反序列化对象(即,将字符串转化成对象),可以使用JSON.parse函数来完成。同样,在第5版之前要从json2库中获取这个函数,在第5版中已经加入这个标准函数。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var christmasList = {mike:"Book", jason:"sweater", chelsea:"iPad" }
JSON.stringify (christmasList);
// Prints this string:
// "{"mike":"Book","jason":"sweater","chels":"iPad"}"

// To print a stringified object with formatting, add "null" and "4" as parameters:
JSON.stringify (christmasList, null, 4);
// "{
// "mike": "Book",
// "jason": "sweater",
// "chels": "iPad"
// }"

// JSON.parse Examples
// The following is a JSON string, so we cannot access the properties with dot notation (like christmasListStr.mike)
var christmasListStr = '{"mike":"Book","jason":"sweater","chels":"iPad"}';

// Let’s convert it to an object
var christmasListObj = JSON.parse (christmasListStr);

// Now that it is an object, we use dot notation
console.log(christmasListObj.mike); // Book
由 Hexo 驱动 & 主题 Keep
本站由 提供部署服务