您现在的位置是:网站首页 > 对象基础文章详情
对象基础
陈川
【
JavaScript
】
10076人已围观
5724字
JavaScript中的对象是一种复合数据类型,用于存储键值对的集合。对象可以包含属性和方法,属性是对象的特征,方法是对象的行为。理解对象的基础概念对于编写高效、可维护的代码至关重要。
对象的创建与基本结构
对象可以通过字面量方式直接创建,也可以使用构造函数或Object.create()
方法生成。字面量是最常见的方式:
const person = {
name: '张三',
age: 30,
greet: function() {
console.log(`你好,我是${this.name}`);
}
};
对象由属性和方法组成,属性是键值对,键是字符串(或Symbol),值可以是任意数据类型。方法本质上是函数类型的属性。
属性的访问与操作
访问对象属性有两种方式:点表示法和方括号表示法:
console.log(person.name); // "张三"
console.log(person['age']); // 30
方括号表示法在属性名包含特殊字符或需要动态访问时特别有用:
const key = 'age';
console.log(person[key]); // 30
添加和修改属性可以直接赋值:
person.job = '工程师'; // 添加新属性
person.age = 31; // 修改现有属性
删除属性使用delete
操作符:
delete person.job;
对象的方法
方法是存储在对象属性中的函数。方法可以通过this
关键字访问对象的其他属性和方法:
const calculator = {
value: 0,
add: function(num) {
this.value += num;
},
subtract: function(num) {
this.value -= num;
},
getValue: function() {
return this.value;
}
};
calculator.add(5);
calculator.subtract(2);
console.log(calculator.getValue()); // 3
构造函数与原型
构造函数用于创建特定类型的对象。通过new
关键字调用构造函数会创建一个新对象:
function Person(name, age) {
this.name = name;
this.age = age;
this.greet = function() {
console.log(`你好,我是${this.name}`);
};
}
const person1 = new Person('李四', 25);
person1.greet(); // "你好,我是李四"
每个函数都有一个prototype
属性,用于实现继承和共享方法:
Person.prototype.sayAge = function() {
console.log(`我今年${this.age}岁`);
};
person1.sayAge(); // "我今年25岁"
对象枚举与属性描述符
可以使用for...in
循环枚举对象的可枚举属性:
for (const key in person1) {
console.log(`${key}: ${person1[key]}`);
}
属性描述符控制属性的行为,可以通过Object.getOwnPropertyDescriptor()
获取:
const descriptor = Object.getOwnPropertyDescriptor(person1, 'name');
console.log(descriptor);
/*
{
value: "李四",
writable: true,
enumerable: true,
configurable: true
}
*/
可以定义新属性或修改现有属性的特性:
Object.defineProperty(person1, 'id', {
value: '12345',
writable: false,
enumerable: false
});
person1.id = '67890'; // 静默失败,严格模式下会报错
console.log(person1.id); // "12345"
对象解构与展开
ES6引入的对象解构可以方便地从对象中提取属性:
const { name, age } = person1;
console.log(name, age); // "李四" 25
对象展开运算符...
可以用于合并对象:
const defaults = { color: 'red', size: 'medium' };
const custom = { size: 'large' };
const combined = { ...defaults, ...custom };
console.log(combined); // { color: "red", size: "large" }
对象比较与引用
对象是通过引用比较的,而不是值比较:
const obj1 = { a: 1 };
const obj2 = { a: 1 };
const obj3 = obj1;
console.log(obj1 === obj2); // false
console.log(obj1 === obj3); // true
要比较对象内容,可以手动比较属性或使用工具函数:
function shallowEqual(obj1, obj2) {
const keys1 = Object.keys(obj1);
const keys2 = Object.keys(obj2);
if (keys1.length !== keys2.length) return false;
for (const key of keys1) {
if (obj1[key] !== obj2[key]) return false;
}
return true;
}
console.log(shallowEqual(obj1, obj2)); // true
对象与JSON
JSON(JavaScript Object Notation)是一种轻量级数据交换格式,与JavaScript对象字面量类似:
const jsonStr = '{"name":"王五","age":28}';
const obj = JSON.parse(jsonStr);
console.log(obj.name); // "王五"
const newJsonStr = JSON.stringify(obj);
console.log(newJsonStr); // '{"name":"王五","age":28}'
对象的高级特性
ES6引入了计算属性名,允许在对象字面量中使用表达式作为属性名:
const propKey = 'user_' + Math.floor(Math.random() * 1000);
const user = {
[propKey]: '匿名用户'
};
console.log(user); // { user_123: "匿名用户" }
对象方法的简写形式:
const car = {
brand: 'Toyota',
// 传统方法定义
honk: function() {
console.log('Beep beep!');
},
// ES6方法简写
drive() {
console.log('Vroom vroom!');
}
};
对象的不可变性
有时需要创建不可变对象,可以使用以下方法:
- 使用
Object.freeze()
防止对象被修改:
const frozen = Object.freeze({ a: 1 });
frozen.a = 2; // 静默失败,严格模式下会报错
console.log(frozen.a); // 1
- 使用
Object.seal()
防止添加或删除属性,但允许修改现有属性:
const sealed = Object.seal({ a: 1 });
sealed.a = 2; // 允许
sealed.b = 3; // 静默失败
delete sealed.a; // 静默失败
对象与迭代
ES6使对象可迭代,可以通过Symbol.iterator
实现:
const iterableObj = {
data: [1, 2, 3],
[Symbol.iterator]() {
let index = 0;
return {
next: () => {
if (index < this.data.length) {
return { value: this.data[index++], done: false };
} else {
return { done: true };
}
}
};
}
};
for (const num of iterableObj) {
console.log(num); // 1, 2, 3
}
对象与类
ES6引入了类语法,本质上是构造函数的语法糖:
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
class Dog extends Animal {
constructor(name) {
super(name);
}
speak() {
console.log(`${this.name} barks.`);
}
}
const dog = new Dog('Rex');
dog.speak(); // "Rex barks."
对象与this绑定
this
的指向在JavaScript中是一个常见问题。箭头函数不绑定自己的this
,而是继承外层作用域的this
:
const counter = {
count: 0,
increment: function() {
setInterval(() => {
this.count++;
console.log(this.count);
}, 1000);
}
};
counter.increment(); // 1, 2, 3...
对象与代理
ES6的Proxy可以拦截和自定义对象的基本操作:
const target = { message: 'hello' };
const handler = {
get: function(target, prop) {
if (prop === 'message') {
return target[prop].toUpperCase();
}
return target[prop];
}
};
const proxy = new Proxy(target, handler);
console.log(proxy.message); // "HELLO"
对象与反射
Reflect API提供了操作对象的方法,与Proxy handlers的方法一一对应:
const obj = { a: 1 };
Reflect.set(obj, 'b', 2);
console.log(Reflect.get(obj, 'b')); // 2
console.log(Reflect.has(obj, 'a')); // true