JavaScript 对象定义
在 JavaScript 中,对象是王。如果您理解了对象,就理解了 JavaScript。
在 JavaScript 中,几乎“所有事物”都是对象。
- 布尔是对象(如果用 new 关键词定义)
- 数字是对象(如果用 new 关键词定义)
- 字符串是对象(如果用 new 关键词定义)
- 日期永远都是对象
- 算术永远都是对象
- 正则表达式永远都是对象
- 数组永远都是对象
- 函数永远都是对象
- 对象永远都是对象
所有 JavaScript 值,除了原始值,都是对象。
JavaScript 对象是易变的
对象是易变的:它们通过引用来寻址,而非值。
这点类似于OC中的浅拷贝。这个特性非常重要。
如果 person 是一个对象,下面的语句不会创建 person 的副本:
var x = person; // 这不会创建 person 的副本。
对象 x 并非 person 的副本。它就是 person。x 和 person 是同一个对象。
对 x 的任何改变都将改变 person,因为 x 和 person 是相同的对象。
var person = {firstName:"Bill", lastName:"Gates", age:62, eyeColor:"blue"}
var x = person;
x.age = 10; // 这将同时改变 both x.age 和 person.age
注释:JavaScript 变量不是易变的。只有 JavaScript 对象如此。
JavaScript 对象属性
JavaScript 属性
属性指的是与 JavaScript 对象相关的值。
JavaScript 对象是无序属性的集合。
属性通常可以被修改、添加和删除,但是某些属性是只读的。
访问 JavaScript 属性
objectName.property
objectName["property"]
objectName[expression]
JavaScript for...in 循环
JavaScript for...in 语句遍历对象的属性。
语法
for (variable in object) {
要执行的代码
}
for...in 循环中的代码块会为每个属性执行一次。
循环对象的属性:
实例
var person = {fname:"Bill", lname:"Gates", age:62}; s
//x 得到的是属性名称
for (x in person) {
txt += person[x];
}
添加新属性
person.nationality = "English";
删除属性
var person = {firstName:"Bill", lastName:"Gates", age:62, eyeColor:"blue"};
delete person.age;
delete 关键词会同时删除属性的值和属性本身。
删除完成后,属性在被添加回来之前是无法使用的。
delete 操作符被设计用于对象属性。它对变量或函数没有影响。
delete 操作符不应被用于预定义的 JavaScript 对象属性。这样做会使应用程序崩溃。
原型属性
这个有待实践
JavaScript 对象继承了它们的原型的属性。
delete 关键词不会删除被继承的属性,但是如果您删除了某个原型属性,则将影响到所有从原型继承的对象。
JavaScript 对象方法
var person = {
firstName: "Bill",
lastName : "Gates",
id : 648,
fullName : function() {
return this.firstName + " " + this.lastName;
}
};
JavaScript 方法
JavaScript 方法是能够在对象上执行的动作。
JavaScript 方法是包含函数定义的属性。
| 属性 | 值 |
|---|---|
| firstName | Bill |
| lastName | Gates |
| age | 62 |
| eyeColor | blue |
| fullName | function() {return this.firstName + " " + this.lastName;} |
方法是存储为对象属性的函数。
this 关键词
在 JavaScript 中,被称为 this 的事物,指的是拥有该 JavaScript 代码的对象。
this 的值,在函数中使用时,是“拥有”该函数的对象。
请注意 this 并非变量。它是关键词。您无法改变 this 的值。
访问对象方法
请使用如下语法创建对象方法:
methodName : function() { 代码行 }
请通过如下语法来访问对象方法:
objectName.methodName()
使用内建方法
此例使用 String 对象的 toUpperCase() 方法,把文本转换为大写:
var message = "Hello world!";
var x = message.toUpperCase();
x 的值,在以上代码执行后将是:
HELLO WORLD!
添加新的方法
向对象添加方法是在构造器函数内部完成的:
实例
function person(firstName, lastName, age, eyeColor) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
this.eyeColor = eyeColor;
this.changeName = function (name) {
this.lastName = name;
};
}
changeName() 函数 name 的值赋给了 person 的 lastName 属性。
现在您可以尝试:
myMother.changeName("Jobs");
通过用 myMother “替代” this,JavaScript 清楚您指的是哪个 person。
JavaScript 显示对象
显示对象属性
对象的属性可显示为字符串:
const person = {
name: "Bill",
age: 19,
city: "Seattle"
};
document.getElementById("demo").innerHTML =
person.name + "," + person.age + "," + person.city;
在循环中显示对象
可以在循环中收集对象的属性:
const person = {
name: "Bill",
age: 19,
city: "Seattle"
};
let txt = "";
for (let x in person) {
txt += person[x] + " ";
};
document.getElementById("demo").innerHTML = txt;
您必须在循环中使用 person[x]。
person.x 将不起作用(因为 x 是一个变量)。
使用 Object.values()
通过使用 Object.values(),任何 JavaScript 对象都可以被转换为数组:
const person = {
name: "Bill",
age: 19,
city: "Seattle"
};
const myArray = Object.values(person);
myArray 现在是 JavaScript 数组,可以显示了:
自 2016 年以来,所有主要浏览器都支持 Object.values()。
| Chrome | IE | Firefox | Safari | Opera |
|---|---|---|---|---|
| 54 (2016) | 14 (2016) | 47 (2016) | 10 (2016) | 41 (2016) |
使用 JSON.stringify()
任何 JavaScript 对象都可以使用 JavaScript 函数 JSON.stringify() 进行字符串化(转换为字符串):
const person = {
name: "Bill",
age: 19,
city: "Seattle"
};
let myString = JSON.stringify(person);
日期字符串化
JSON.stringify 将日期转换为字符串:
const person = {
name: "Bill",
today: new Date()
};
let myString = JSON.stringify(person);
//{"name":"Bill","today":"2022-09-16T07:32:51.949Z"}
document.getElementById("demo").innerHTML = myString;
函数字符串化
JSON.stringify 不会对函数进行字符串化:
如果在字符串化之前将函数转换为字符串:
const personThree = {
name: "Bill",
today: new Date(),
age: function () {return 19;}
};
personThree.age = personThree.age.toString();
let myString = JSON.stringify(personThree);
//{"name":"Bill","today":"2022-09-16T07:35:04.174Z","age":"function () {return 19;}"}
document.getElementById("demo").innerHTML = myString;
数组字符串化
也可以对 JavaScript 数组进行字符串化:
实例
const arr = ["Bill", "Steve", "Elon", "David"];
let myString = JSON.stringify(arr);
document.getElementById("demo").innerHTML = myString;
JavaScript 对象访问器
JavaScript 访问器(Getter 和 Setter)
ECMAScript 5 (2009) 引入了 Getter 和 Setter。
Getter 和 Setter 允许您定义对象访问器(被计算的属性)。
JavaScript Getter(get 关键词)
本例使用 lang 属性来获取 language 属性的值。
// 创建对象:
var person = {
firstName: "Bill",
lastName : "Gates",
language : "en",
get lang() {
return this.language;
}
};
// 使用 getter 来显示来自对象的数据:
document.getElementById("demo").innerHTML = person.lang;
JavaScript Setter(set 关键词)
本例使用 lang 属性来设置 language 属性的值。
实例
var person = {
firstName: "Bill",
lastName : "Gates",
language : "",
set lang(lang) {
this.language = lang;
}
};
// 使用 setter 来设置对象属性:
person.lang = "en";
// 显示来自对象的数据:
document.getElementById("demo").innerHTML = person.language;
JavaScript 函数还是 Getter?
下面两个例子的区别在哪里?
例子 1
var person = {
firstName: "Bill",
lastName : "Gates",
fullName : function() {
return this.firstName + " " + this.lastName;
}
};
// 使用方法来显示来自对象的数据:
document.getElementById("demo").innerHTML = person.fullName();
例子 2
var person = {
firstName: "Bill",
lastName : "Gates",
get fullName() {
return this.firstName + " " + this.lastName;
}
};
// 使用 getter 来显示来自对象的数据:
document.getElementById("demo").innerHTML = person.fullName;
例子 1 以函数形式访问 fullName:person.fullName()。
例子 2 以属性形式访问 fullName:person.fullName。
第二个例子提供了更简洁的语法。
Object.defineProperty() 方法也可用于添加 Getter 和 Setter:
// 定义对象
var obj = {counter : 0};
// 定义 setters
Object.defineProperty(obj, "reset", {
get : function () {this.counter = 0;}
});
Object.defineProperty(obj, "increment", {
get : function () {this.counter++;}
});
Object.defineProperty(obj, "decrement", {
get : function () {this.counter--;}
});
Object.defineProperty(obj, "add", {
set : function (value) {this.counter += value;}
});
Object.defineProperty(obj, "subtract", {
set : function (value) {this.counter -= value;}
});
// 操作计数器:
obj.reset;
obj.add = 5;
obj.subtract = 1;
obj.increment;
obj.decrement;
浏览器支持
Internet Explorer 8 或更早的版本不支持 Getter 和 Setter:
| Yes | 9.0 | Yes | Yes | Yes |
JavaScript 对象构造器
实例
function Person(first, last, age, eye) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eye;
}
为对象添加属性
var myFather = new Person("Bill", "Gates", 62, "blue");
var myMother = new Person("Steve", "Jobs", 56, "green");
//新属性被添加到 myFather。不是 myMother,也不是任何其他 person 对象。
myFather.nationality = "English";
为对象添加方法
myFather.name = function () {
return this.firstName + " " + this.lastName;
};
新方法被添加到 myFather。不是 myMother,也不是任何其他 person 对象。
为构造器添加属性
与向已有对象添加新属性不同,您无法为对象构造器添加新属性:
实例
Person.nationality = "English";
如需向构造器添加一个新属性,您必须添加到构造器函数:
实例
function Person(first, last, age, eyecolor) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eyecolor;
this.nationality = "English";
}
JavaScript 对象原型
原型继承
所有 JavaScript 对象都从原型继承属性和方法。
日期对象继承自 Date.prototype。数组对象继承自 Array.prototype。Person 对象继承自 Person.prototype。
Object.prototype 位于原型继承链的顶端:
日期对象、数组对象和 Person 对象都继承自 Object.prototype。
使用 prototype 属性
JavaScript prototype 属性允许您为对象构造器添加新属性:
function Person(first, last, age, eyecolor) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eyecolor;
}
Person.prototype.nationality = "English";
JavaScript prototype 属性也允许您为对象构造器添加新方法:
function Person(first, last, age, eyecolor) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eyecolor;
}
Person.prototype.name = function() {
return this.firstName + " " + this.lastName;
};
JavaScript ES5 对象方法
ECMAScript 5 (2009) 向 JavaScript 添加了许多新的对象方法。
管理对象
// 以现有对象为原型创建对象
Object.create()
// 添加或更改对象属性
Object.defineProperty(object, property, descriptor)
// 添加或更改对象属性
Object.defineProperties(object, descriptors)
// 访问属性
Object.getOwnPropertyDescriptor(object, property)
// 以数组返回所有属性
Object.getOwnPropertyNames(object)
// 访问原型
Object.getPrototypeOf(object)
// 以数组返回可枚举属性
Object.keys(object)
保护对象
// 防止向对象添加属性
Object.preventExtensions(object)
// 如果属性可以添加到对象,则返回 true
Object.isExtensible(object)
// 防止更改对象属性(不是值)
Object.seal(object)
// 如果对象被密封,则返回 true
Object.isSealed(object)
// 防止对对象进行任何更改
Object.freeze(object)
// 如果对象被冻结,则返回 true
Object.isFrozen(object)
更改属性值
语法
Object.defineProperty(object, property, {value : value})
实例
此例更改属性值:
const person = {
firstName: "Bill",
lastName : "Gates",
language : "EN"
};
// 修改属性
Object.defineProperty(person, "language", {value : "NO"});
更改元数据
ES5 允许更改以下属性元数据:
writable : true // 属性值可更改
enumerable : true // 属性可枚举
configurable : true // 属性可重新配置
writable : false // 属性值不可更改
enumerable : false // 属性不可枚举
configurable : false // 属性不可重新配置
ES5 允许更改 getter 和 setter:
// 定义 getter
get: function() { return language }
// 定义 setter
set: function(value) { language = value }
此例设置 language 为只读:
Object.defineProperty(person, "language", {writable:false});
这个例子使 language 不可枚举:
Object.defineProperty(person, "language", {enumerable:false});
列出所有属性
这个例子列出了一个对象的所有属性:
实例
const person = {
firstName: "Bill",
lastName : "Gates",
language : "EN"
};
Object.defineProperty(person, "language", {enumerable:false});
Object.getOwnPropertyNames(person); // 返回数组的数组
添加属性
此例向对象添加新属性:const声明的对象也可以添加哦
实例
// 创建对象
const person = {
firstName: "Bill",
lastName : "Gates",
language : "EN"
};
// 添加属性
Object.defineProperty(person, "year", {value:"2008"});
添加 Getter 和 Setter
Object.defineProperty() 方法也可以用来添加 Getter 和 Setter:
// 创建对象
const person = {firstName:"Bill", lastName:"Gates"};
// 定义 getter
Object.defineProperty(person, "fullName", {
get: function () {return this.firstName + " " + this.lastName;}
});
JavaScript Map 对象
Map 对象存有键值对,其中的键可以是任何数据类型。
Map 对象记得键的原始插入顺序。
Map 对象具有表示映射大小的属性。
基本的 Map() 方法
| Method | Description |
|---|---|
| new Map() | 创建新的 Map 对象。 |
| set() | 为 Map 对象中的键设置值。 |
| get() | 获取 Map 对象中键的值。 |
| entries() | 返回 Map 对象中键/值对的数组。 |
| keys() | 返回 Map 对象中键的数组。 |
| values() | 返回 Map 对象中值的数组。 |
Map() 属性
| Property | Description |
|---|---|
| size | 获取 Map 对象中某键的值。 |
创建 Map 对象
能够使用对象作为键是 Map 的一个重要特性。
// 创建对象
const apples = {name: 'Apples'};
const bananas = {name: 'Bananas'};
const oranges = {name: 'Oranges'};
// 创建新的 Map
const fruits = new Map();
// Add new Elements to the Map
fruits.set(apples, 500);
fruits.set(bananas, 300);
fruits.set(oranges, 200);
您可以将 Array 传递给 new Map() 构造函数:
// 返回
const apples = {name: 'Apples'};
const bananas = {name: 'Bananas'};
const oranges = {name: 'Oranges'};
// 创建新的 Map
const fruits = new Map([
[apples, 500],
[bananas, 300],
[oranges, 200]
]);
获取键的值
get() 方法获取 Map 中键的值:
实例
fruits.get(apples); // 返回 500
get里面需要是apples对象
其他 Map() 方法
| 方法 | 描述 |
|---|---|
| clear() | 删除 Map 中的所有元素。 |
| delete() | 删除由键指定的元素。 |
| has() | 如果键存在,则返回 true。 |
| forEach() | 为每个键/值对调用回调。 |
JavaScript 对象 vs Map
JavaScript 对象和 Map 之间的差异:
| 对象 | Map | |
|---|---|---|
| Size | 对象没有 size 属性 | Maps 有 size 属性 |
| 键类型 | 对象键必须是字符串(或符号) | Map 键可以是任何数据类型 |
| 键顺序 | 对象键没有很好地排序 | Map 键按插入排序 |
| 默认 | 对象有默认键 | Map 没有默认键 |
JavaScript Set 对象
Set 是唯一值的集合。
每个值在 Set 中只能出现一次。
一个 Set 可以容纳任何数据类型的任何值
好像每个语言的Set都是这种特性
如何创建 Set
创建一个 Set 并添加现有变量:
// 创建 Set
const letters = new Set();
// 向 Set 添加一些值
letters.add("a");
letters.add("b");
letters.add("c");
将 Array 传递给 new Set() 构造函数:
// 创建新的 Set
const letters = new Set(["a","b","c"]);
对于 Set,typeof 返回对象:
typeof letters; // 返回 object。
对于 Set,instanceof Set 返回 true:
letters instanceof Set; // 返回 true
Set 对象的方法和属性
| new Set() | 创建新的 Set 对象。 |
|---|---|
| add() | 向 Set 添加新元素。 |
| clear() | 从 Set 中删除所有元素。 |
| delete() | 删除由其值指定的元素。 |
| entries() | 返回 Set 对象中值的数组。 |
| has() | 如果值存在则返回 true。 |
| forEach() | 为每个元素调用回调。 |
| keys() | 返回 Set 对象中值的数组。 |
| values() | 与 keys() 相同。 |
| size | 返回元素计数。 |