JS学习——对象
学习内容来源:JavaScript 对象定义、JavaScript 对象属性、JavaScript 对象方法、JavaScript 对象访问器、JavaScript 对象构造器、JavaScript 对象原型、JavaScript ES5 对象方法
JavaScript 对象定义
在 JavaScript 中,对象是王。如果您理解了对象,就理解了 JavaScript。
在 JavaScript 中,几乎“所有事物”都是对象。
- 布尔是对象(如果用 new 关键词定义)
- 数字是对象(如果用 new 关键词定义)
- 字符串是对象(如果用 new 关键词定义)
- 日期永远都是对象
- 算术永远都是对象
- 正则表达式永远都是对象
- 数组永远都是对象
- 函数永远都是对象
- 对象永远都是对象
所有 JavaScript 值,除了原始值,都是对象。
JavaScript 原始值
原始值指的是没有属性或方法的值。
原始数据类型指的是拥有原始值的数据。
原始值是一成不变的(它们是硬编码的,因此不能改变)。
JavaScript 定义了 5 种原始数据类型:
- string
- number
- boolean
- null
- undefined
值 | 类型 | 解释 |
---|---|---|
"Hello" | string | "Hello" 始终是 "Hello" |
3.14 | number | 3.14 始终是 3.14 |
true | boolean | true 始终是 true |
false | boolean | false 始终是 false |
null | null | (object) null 始终是 null |
undefined | undefined | undefined 始终是 undefined |
对象是包含变量的变量
对象也是变量。但是对象能够包含很多值。
值按照名称 : 值对的形式编写(名称和值以冒号分隔)。
JavaScript 对象是命名值的集合。
例子:
var person = {
firstName: "Bill",
lastName: "Gates",
age: 62,
eyeColor: "blue"
};
对象属性
JavaScript 对象中的命名值,被称为属性。
属性指的是与 JavaScript 对象相关的值。
JavaScript 对象是无序属性的集合。
属性通常可以被修改、添加和删除,但是某些属性是只读的。
属性 | 值 |
---|---|
firstName | Bill |
lastName | Gates |
age | 62 |
eyeColor | blue |
访问 JavaScript 属性
访问对象属性的语法是:
objectName.property // person.age
objectName["property"] // person["age"]
objectName[expression] // x = "age"; person[x] 表达式必须计算为属性名。
JavaScript for...in 循环
JavaScript for...in 语句遍历对象的属性。
for...in 循环中的代码块会为每个属性执行一次。
例子:
// txt = 'Bill Gates 62 '
var person = {fname:"Bill", lname:"Gates", age:62};
var txt;
for (x in person) {
txt += person[x]; // 注意:必须在循环中使用 person[x],person.x 将不起作用(因为 x 是一个变量)。
}
添加新属性
可以通过简单的赋值,向已存在的对象添加新属性。
objectName.property = value // person.age = "18"
objectName["property"] = value // person["age"] = "18"
删除属性
delete 关键词从对象中删除属性。
delete 关键词会同时删除属性的值和属性本身。
删除完成后,属性在被添加回来之前是无法使用的。
注意:delete 关键词不会删除被继承的属性,但是如果您删除了某个原型属性,则将影响到所有从原型继承的对象。
var person = {
firstName: "Bill",
lastName: "Gates",
age: 62,
eyeColor: "blue"
};
delete person.age; // 或 delete person["age"];
对象方法
方法是可以在对象上执行的动作。
对象属性可以是原始值、其他对象以及函数。
对象方法是包含函数定义的对象属性。
属性 | 值 |
---|---|
firstName | Bill |
lastName | Gates |
age | 62 |
eyeColor | blue |
fullName | function() |
访问对象方法
var person = {
firstName: "Bill",
lastName : "Gates",
id : 12345,
fullName : function() {
return this.firstName + " " + this.lastName;
}
};
let name = person.fullName(); // 访问 person 对象的 fullName() 方法
let nameFunc = person.fullName; // 如果访问 fullName 属性时没有使用 (),则将返回函数定义
使用内建方法
例子:
// 使用 String 对象的 toUpperCase() 方法,把文本转换为大写。x = "HELLO WORLD!"
var message = "Hello world!";
var x = message.toUpperCase();
添加新的方法
向对象添加方法是在构造器函数内部完成的
例子:
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;
};
}
// 通过 myMother 对象调用 changeName
myMother.changeName("Jobs");
创建 JavaScript 对象
有不同的方法来创建对象:
- 定义和创建单个对象,使用对象文字。
- 定义和创建单个对象,通过关键词 new。
- 定义对象构造器,然后创建构造类型的对象。
使用对象字面量
这是创建对象最简答的方法。
使用对象文字,您可以在一条语句中定义和创建对象。
对象文字指的是花括号 {} 中的名称:值对(比如 age:62)。
例子:
// 创建带有四个属性的新的 JavaScript 对象
var person = {
firstName: "Bill",
lastName: "Gates",
age: 62,
eyeColor: "blue"
};
使用 JavaScript 关键词 new
var person = new Object();
person.firstName = "Bill";
person.lastName = "Gates";
person.age = 50;
person.eyeColor = "blue";
提示:出于简易性、可读性和执行速度的考虑,请使用第一种创建方法(对象文字方法)。
JavaScript 对象是易变的
对象是易变的:它们通过引用来寻址,而非值。
// 这不会创建 person 的副本。对象 x 并非 person 的副本。它就是 person。x 和 person 是同一个对象。
var 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 显示对象
使用 Object.values()
通过使用 Object.values(),任何 JavaScript 对象都可以被转换为数组
const person = {
name: "Bill",
age: 19,
city: "Seattle"
};
// myArray 现在是 JavaScript 数组,myArray = ['Bill', 19, 'Seattle']
const myArray = Object.values(person);
使用 JSON.stringify()
任何 JavaScript 对象都可以使用 JavaScript 函数 JSON.stringify() 进行字符串化(转换为字符串)
注意:JSON.stringify 不会对函数进行字符串化。
const person = {
name: "Bill",
age: 19,
city: "Seattle"
};
// myString = {"firstName":"Bill","lastName":"Gates","age":62,"eyeColor":"blue","name":"test","aa":"bb"}
let myString = JSON.stringify(person);
// 如果在字符串化之前将函数转换为字符串,这可以是“固定的”。
// myString = {"name":"Bill","age":"function () {return 19;}"}
const person = {
name: "Bill",
age: function () {return 19;}
};
person.age = person.age.toString();
let myString = JSON.stringify(person);
// 可以对 JavaScript 数组进行字符串化
// myString = ["John","Peter","Sally","Jane"]
const arr = ["John", "Peter", "Sally", "Jane"];
let myString = JSON.stringify(arr);
// 日期字符串化
// myString = {"name":"Bill","today":"2022-03-04T05:10:40.809Z"}
const person = {
name: "Bill",
today: new Date()
};
let myString = JSON.stringify(person);
JavaScript 对象访问器
JavaScript Getter(get 关键词)
// 创建对象:
var person = {
firstName: "Bill",
lastName : "Gates",
language : "en",
get lang() {
return this.language;
}
};
// 使用 getter 来显示来自对象的数据,lang = "en"
let lang = person.lang;
JavaScript Setter(set 关键词)
var person = {
firstName: "Bill",
lastName : "Gates",
language : "",
set lang(lang) {
this.language = lang;
}
};
// 使用 setter 来设置对象属性,person 对象的 language 属性值被修改为 "en"
person.lang = "en";
为什么使用 Getter 和 Setter?
- 它提供了更简洁的语法
- 它允许属性和方法的语法相同
- 它可以确保更好的数据质量
- 有利于后台工作
var obj = {
counter: 0,
get increment() {
this.counter++;
},
get decrement() {
this.counter--;
},
set add(value) {
this.counter += value;
}
}
// Object.defineProperty() 方法也可用于添加 Getter 和 Setter
var obj = { counter: 0 };
Object.defineProperty(obj, "increment", {
get : function () {
this.counter = 0;
}
})
JavaScript 对象构造器
// 用大写首字母对构造器函数命名是个好习惯。
function Person(first, last, age, eye) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eye;
}
// 通过 new 关键词调用构造器函数可以创建相同类型的对象
var myFather = new Person("Bill", "Gates", 62, "blue");
var myMother = new Person("Steve", "Jobs", 56, "green");
注意:在构造器函数中,this 是没有值的。它是新对象的替代物。 当一个新对象被创建时,this 的值会成为这个新对象。
为构造器添加属性
与向已有对象添加新属性不同,无法为对象构造器添加新属性
如需向构造器添加一个新属性,您必须添加到构造器函数
function Person(first, last, age, eyecolor) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eyecolor;
this.nationality = "English";
}
为构造器添加方法
与向已有对象添加新方法不同,无法为对象构造器添加新方法
必须在构造器函数内部向一个对象添加方法
// changeName 函数把 name 赋值给 lastName
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;
};
}
// 创建 myMother 对象
var myMother = new Person("Steve", "Jobs", 56, "green");
// myMother 对象的 lastName 属性值被修改为 "Job"
myMother.changeName("Job");
内建 JavaScript 构造器
JavaScript 提供用于原始对象的构造器
var x1 = new Object(); // 一个新的 Object 对象
var x2 = new String(); // 一个新的 String 对象
var x3 = new Number(); // 一个新的 Number 对象
var x4 = new Boolean(); // 一个新的 Boolean 对象
var x5 = new Array(); // 一个新的 Array 对象
var x6 = new RegExp(); // 一个新的 RegExp 对象
var x7 = new Function(); // 一个新的 Function 对象
var x8 = new Date(); // 一个新的 Date 对象
注意:JavaScript 提供原始数据类型字符串、数字和布尔的对象版本。但是并无理由创建复杂的对象。原始值快得多!
var x1 = {}; // 新对象
var x2 = ""; // 新的原始字符串
var x3 = 0; // 新的原始数值
var x4 = false; // 新的原始逻辑值
var x5 = []; // 新的数组对象
var x6 = /()/ // 新的正则表达式对象
var x7 = function(){}; // 新的函数对象
JavaScript 对象原型
所有 JavaScript 对象都从原型继承属性和方法。
注意:请只修改您自己的原型。绝不要修改标准 JavaScript 对象的原型。
原型继承
- 日期对象继承自 Date.prototype。数组对象继承自 Array.prototype。Person 对象继承自Person.prototype
- Object.prototype 位于原型继承链的顶端
- 日期对象、数组对象和 Person 对象都继承自 Object.prototype
向对象添加属性和方法
使用 prototype 属性
function Person(first, last, age, eyecolor) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eyecolor;
}
// 在 Person 的 prototype 属性中添加 nationality: "English"
Person.prototype.nationality = "English";
// 创建 myFriend 对象,myFriend.nationality = "English"
var myFriend = new Person("Bill", "Gates", 62, "blue");
// 也允许为对象构造器添加新方法,myFriend.name = "Bill Gates"
Person.prototype.name = function() {
return this.firstName + " " + this.lastName;
};
JavaScript ES5 对象方法
管理对象
// 以现有对象为原型创建对象
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)
例子:
更改属性值
const person = {
firstName: "Bill",
lastName : "Gates",
language : "EN"
};
// 修改属性
Object.defineProperty(person, "language", {value : "NO"});
更改元数据
writable : true // 属性值可更改
enumerable : true // 属性可枚举
configurable : true // 属性可重新配置
writable : false // 属性值不可更改
enumerable : false // 属性不可枚举
configurable : false // 属性不可重新配置
const person = {
firstName: "Bill",
lastName : "Gates",
language : "EN"
};
// 设置 language 为只读
Object.defineProperty(person, "language", {writable:false});
// 使 language 不可枚举
Object.defineProperty(person, "language", {enumerable:false});
// 列出所有属性,['firstName', 'lastName', 'language']
Object.getOwnPropertyNames(person); // 返回所有属性的数组
// 列出可枚举的属性,['firstName', 'lastName']
Object.keys(person); // 返回可枚举属性的数组