JavaScript对象知识点大全
编程小白也能理解的详细指南
对象是JavaScript编程的核心概念之一。就像现实世界中的物体一样,JS对象也有自己的特性(属性)和行为(方法)。这份指南将用简单易懂的语言和丰富示例,带你全面了解JavaScript对象。
1. 什么是JavaScript对象?
可以把JavaScript对象想象成一个收纳盒,这个盒子可以存放各种相关的数据和功能。
现实世界类比
想象一辆汽车:
- 它有属性:颜色(红色)、品牌(丰田)、型号(凯美瑞)
- 它有方法(功能):启动、加速、刹车
// 创建一个汽车对象
let car = {
// 属性
color: “红色”,
brand: “丰田”,
model: “凯美瑞”,
year: 2020,
// 方法
start: function() {
console.log(“汽车启动了!”);
},
accelerate: function() {
console.log(“汽车在加速…”);
}
};
// 访问属性和调用方法
console.log(car.color); // 输出:”红色”
car.start(); // 输出:”汽车启动了!”
let car = {
// 属性
color: “红色”,
brand: “丰田”,
model: “凯美瑞”,
year: 2020,
// 方法
start: function() {
console.log(“汽车启动了!”);
},
accelerate: function() {
console.log(“汽车在加速…”);
}
};
// 访问属性和调用方法
console.log(car.color); // 输出:”红色”
car.start(); // 输出:”汽车启动了!”
2. 创建和使用对象
创建对象有几种常用方法:
方法1:对象字面量(最常用)
let person = {
name: “张三”,
age: 25,
hobbies: [“阅读”, “游泳”, “编程”],
greet: function() {
console.log(`你好,我是${this.name},今年${this.age}岁!`);
}
};
name: “张三”,
age: 25,
hobbies: [“阅读”, “游泳”, “编程”],
greet: function() {
console.log(`你好,我是${this.name},今年${this.age}岁!`);
}
};
方法2:使用 new Object()
let person = new Object();
person.name = “张三”;
person.age = 25;
person.greet = function() {
console.log(`你好,我是${this.name}!`);
};
person.name = “张三”;
person.age = 25;
person.greet = function() {
console.log(`你好,我是${this.name}!`);
};
方法3:使用构造函数
// 构造函数(首字母大写)
function Person(name, age) {
this.name = name;
this.age = age;
this.greet = function() {
console.log(`你好,我是${this.name}!`);
};
}
// 创建对象实例
let person1 = new Person(“张三”, 25);
let person2 = new Person(“李四”, 30);
function Person(name, age) {
this.name = name;
this.age = age;
this.greet = function() {
console.log(`你好,我是${this.name}!`);
};
}
// 创建对象实例
let person1 = new Person(“张三”, 25);
let person2 = new Person(“李四”, 30);
关键点理解
this关键字: 在对象方法中,this
指向当前对象本身。就像说”我的车”中的”我”指的是说话的人。
访问属性: 使用点表示法person.name
或方括号表示法person["name"]
3. 对象的高级概念
原型(Prototype)
每个JavaScript对象都有一个原型,可以把它看作对象的”基因”或”祖先”,对象可以继承原型的属性和方法。
// 创建对象
let animal = {
eats: true
};
// 创建新对象,以animal为原型
let rabbit = Object.create(animal);
rabbit.jumps = true;
console.log(rabbit.eats); // true (从原型继承)
console.log(rabbit.jumps); // true (自有属性)
let animal = {
eats: true
};
// 创建新对象,以animal为原型
let rabbit = Object.create(animal);
rabbit.jumps = true;
console.log(rabbit.eats); // true (从原型继承)
console.log(rabbit.jumps); // true (自有属性)
原型链
当访问对象属性时,如果对象自身没有该属性,JavaScript会沿着原型链向上查找,直到找到该属性或到达链条末端。
现实世界类比
就像家族继承:
- 你自己没有车 → 查你父母有没有车
- 父母没有 → 查祖父母有没有
- 直到找到或确认家族中没有人有车
ES6类(Class)
class是创建对象的模板,是一种更清晰的创建对象和实现继承的方式。
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name}发出声音`);
}
}
class Dog extends Animal {
constructor(name) {
super(name); // 调用父类的构造函数
}
speak() {
console.log(`${this.name}汪汪叫!`);
}
}
let myDog = new Dog(“小白”);
myDog.speak(); // “小白汪汪叫!”
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name}发出声音`);
}
}
class Dog extends Animal {
constructor(name) {
super(name); // 调用父类的构造函数
}
speak() {
console.log(`${this.name}汪汪叫!`);
}
}
let myDog = new Dog(“小白”);
myDog.speak(); // “小白汪汪叫!”
4. 对象常用操作
访问属性
let person = { name: “张三”, age: 25 };
// 点表示法
console.log(person.name); // “张三”
// 方括号表示法(当属性名包含特殊字符或在变量中时很有用)
console.log(person[“age”]); // 25
let prop = “name”;
console.log(person[prop]); // “张三”
// 点表示法
console.log(person.name); // “张三”
// 方括号表示法(当属性名包含特殊字符或在变量中时很有用)
console.log(person[“age”]); // 25
let prop = “name”;
console.log(person[prop]); // “张三”
添加/修改属性
person.job = “程序员”; // 添加新属性
person.age = 26; // 修改已有属性
person.age = 26; // 修改已有属性
删除属性
delete person.age; // 删除age属性
console.log(person.age); // undefined
console.log(person.age); // undefined
遍历对象
let person = { name: “张三”, age: 25, job: “程序员” };
// for…in 循环
for (let key in person) {
console.log(`${key}: ${person[key]}`);
}
// Object.keys() 获取所有属性名
let keys = Object.keys(person);
console.log(keys); // [“name”, “age”, “job”]
// Object.values() 获取所有属性值
let values = Object.values(person);
console.log(values); // [“张三”, 25, “程序员”]
// for…in 循环
for (let key in person) {
console.log(`${key}: ${person[key]}`);
}
// Object.keys() 获取所有属性名
let keys = Object.keys(person);
console.log(keys); // [“name”, “age”, “job”]
// Object.values() 获取所有属性值
let values = Object.values(person);
console.log(values); // [“张三”, 25, “程序员”]
对象解构
从对象中提取属性值到变量中的简洁方法
let person = { name: “张三”, age: 25, job: “程序员” };
// 传统方式
let name = person.name;
let age = person.age;
// 解构方式
let { name, age, job } = person;
console.log(name, age, job); // “张三” 25 “程序员”
// 传统方式
let name = person.name;
let age = person.age;
// 解构方式
let { name, age, job } = person;
console.log(name, age, job); // “张三” 25 “程序员”
5. 对象方法与技巧
合并对象
let obj1 = { a: 1, b: 2 };
let obj2 = { b: 3, c: 4 };
// 合并对象(后者覆盖前者)
let merged = Object.assign({}, obj1, obj2);
console.log(merged); // { a: 1, b: 3, c: 4 }
// 使用扩展运算符(…)
let merged2 = { …obj1, …obj2 };
console.log(merged2); // { a: 1, b: 3, c: 4 }
let obj2 = { b: 3, c: 4 };
// 合并对象(后者覆盖前者)
let merged = Object.assign({}, obj1, obj2);
console.log(merged); // { a: 1, b: 3, c: 4 }
// 使用扩展运算符(…)
let merged2 = { …obj1, …obj2 };
console.log(merged2); // { a: 1, b: 3, c: 4 }
冻结对象
防止对象被修改
let person = { name: “张三” };
Object.freeze(person);
person.name = “李四”; // 无效(严格模式下会报错)
console.log(person.name); // “张三”
Object.freeze(person);
person.name = “李四”; // 无效(严格模式下会报错)
console.log(person.name); // “张三”
获取对象描述符
let obj = { name: “张三” };
let descriptor = Object.getOwnPropertyDescriptor(obj, “name”);
console.log(descriptor);
/* 输出:
{
value: “张三”,
writable: true, // 可修改
enumerable: true, // 可枚举
configurable: true // 可配置
}
*/
let descriptor = Object.getOwnPropertyDescriptor(obj, “name”);
console.log(descriptor);
/* 输出:
{
value: “张三”,
writable: true, // 可修改
enumerable: true, // 可枚举
configurable: true // 可配置
}
*/
JSON和对象的转换
let person = {
name: “张三”,
age: 25,
skills: [“JavaScript”, “HTML”, “CSS”]
};
// 对象转JSON字符串
let jsonString = JSON.stringify(person);
console.log(jsonString); // ‘{“name”:”张三”,”age”:25,”skills”:[“JavaScript”,”HTML”,”CSS”]}’
// JSON字符串转对象
let parsedObj = JSON.parse(jsonString);
console.log(parsedObj.name); // “张三”
name: “张三”,
age: 25,
skills: [“JavaScript”, “HTML”, “CSS”]
};
// 对象转JSON字符串
let jsonString = JSON.stringify(person);
console.log(jsonString); // ‘{“name”:”张三”,”age”:25,”skills”:[“JavaScript”,”HTML”,”CSS”]}’
// JSON字符串转对象
let parsedObj = JSON.parse(jsonString);
console.log(parsedObj.name); // “张三”
6. 常见误区与陷阱
引用类型陷阱
let obj1 = { name: “张三” };
let obj2 = obj1; // obj2和obj1指向同一个对象
obj2.name = “李四”;
console.log(obj1.name); // 输出 “李四”(意外修改)
// 正确做法:创建副本
let obj3 = { …obj1 }; // 使用扩展运算符
obj3.name = “王五”;
console.log(obj1.name); // “李四”(原对象未改变)
let obj2 = obj1; // obj2和obj1指向同一个对象
obj2.name = “李四”;
console.log(obj1.name); // 输出 “李四”(意外修改)
// 正确做法:创建副本
let obj3 = { …obj1 }; // 使用扩展运算符
obj3.name = “王五”;
console.log(obj1.name); // “李四”(原对象未改变)
this指向问题
let person = {
name: “张三”,
greet: function() {
console.log(`你好,我是${this.name}`);
}
};
// 正常情况
person.greet(); // “你好,我是张三”
// this指向丢失的情况
let greetFunc = person.greet;
greetFunc(); // “你好,我是undefined”
// 解决方案1:使用bind绑定this
let boundGreet = person.greet.bind(person);
boundGreet(); // “你好,我是张三”
// 解决方案2:使用箭头函数(ES6)
let person2 = {
name: “李四”,
greet: () => {
console.log(`你好,我是${this.name}`);
}
};
// 注意:箭头函数没有自己的this,会继承外层作用域的this
name: “张三”,
greet: function() {
console.log(`你好,我是${this.name}`);
}
};
// 正常情况
person.greet(); // “你好,我是张三”
// this指向丢失的情况
let greetFunc = person.greet;
greetFunc(); // “你好,我是undefined”
// 解决方案1:使用bind绑定this
let boundGreet = person.greet.bind(person);
boundGreet(); // “你好,我是张三”
// 解决方案2:使用箭头函数(ES6)
let person2 = {
name: “李四”,
greet: () => {
console.log(`你好,我是${this.name}`);
}
};
// 注意:箭头函数没有自己的this,会继承外层作用域的this
for…in遍历原型链
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log(“你好!”);
};
let p = new Person(“张三”);
for (let key in p) {
console.log(key); // 输出 “name” 和 “sayHello”
}
// 只遍历自身属性:
for (let key in p) {
if (p.hasOwnProperty(key)) {
console.log(key); // 只输出 “name”
}
}
this.name = name;
}
Person.prototype.sayHello = function() {
console.log(“你好!”);
};
let p = new Person(“张三”);
for (let key in p) {
console.log(key); // 输出 “name” 和 “sayHello”
}
// 只遍历自身属性:
for (let key in p) {
if (p.hasOwnProperty(key)) {
console.log(key); // 只输出 “name”
}
}