1. objectoverview
object is JavaScriptin core concepts, is a复合dataclass型, 用于store键值 for collection. in JavaScriptin, 几乎所 has 东西都 is object, includingfunction, array, 日期etc.. object允许我们将相关 data and functions组织 in 一起, 使code更加module化 and 可maintenance.
1.1 object 特点
- object is 键值 for collection, 其in键 is string ( or Symbol) , 值可以 is 任何dataclass型
- object is 引用class型, store in 堆memoryin
- object具 has 原型链, 可以inheritanceotherobject property and method
- object is 动态 , 可以随时添加, modify or deleteproperty and method
2. object creation
in JavaScriptin, has many 种creationobject 方式: object字面量, constructfunction, Object.create()methodetc..
2.1 object字面量
object字面量 is 最common, 最简洁 creationobject 方式, using花括号{}:
// object字面量
const person = {
name: "张三",
age: 30,
gender: "男",
greet: function() {
console.log(`你 good , 我 is ${this.name}!`);
}
};
// 访问objectproperty and method
console.log(person.name); // 张三
console.log(person['age']); // 30
person.greet(); // 你 good , 我 is 张三!
2.2 constructfunction
usingconstructfunctioncreationobject, throughnew关键字调用:
// constructfunction
function Person(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
this.greet = function() {
console.log(`你 good , 我 is ${this.name}!`);
};
}
// usingconstructfunctioncreationobject
const person1 = new Person("张三", 30, "男");
const person2 = new Person("李四", 25, "女");
// 访问objectproperty and method
console.log(person1.name); // 张三
console.log(person2.age); // 25
person1.greet(); // 你 good , 我 is 张三!
person2.greet(); // 你 good , 我 is 李四!
2.3 Object.create()method
usingObject.create()methodcreationobject, 可以指定原型object:
// 原型object
const personProto = {
greet: function() {
console.log(`你 good , 我 is ${this.name}!`);
}
};
// usingObject.create()creationobject
const person = Object.create(personProto);
person.name = "张三";
person.age = 30;
person.gender = "男";
// 访问objectproperty and method
console.log(person.name); // 张三
person.greet(); // 你 good , 我 is 张三!
// check原型
console.log(Object.getPrototypeOf(person) === personProto); // true
2.4 class (ES6+)
ES6引入了class concepts, providing了更简洁, 更面向object 语法:
// class定义
class Person {
constructor(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
greet() {
console.log(`你 good , 我 is ${this.name}!`);
}
getAge() {
return this.age;
}
setAge(newAge) {
this.age = newAge;
}
}
// usingclasscreationobject
const person = new Person("张三", 30, "男");
// 访问objectproperty and method
console.log(person.name); // 张三
person.greet(); // 你 good , 我 is 张三!
console.log(person.getAge()); // 30
person.setAge(31);
console.log(person.getAge()); // 31
3. object property and method
object由property and method组成. property is object 特征, method is object behavior.
3.1 property
property is object 键值 for , 其in键 is property名, 值 is property值:
const person = {
// dataproperty
name: "张三",
age: 30,
gender: "男",
// 访问器property (getter and setter)
get fullInfo() {
return `${this.name}, ${this.age}岁, ${this.gender}`;
},
set birthYear(year) {
const currentYear = new Date().getFullYear();
this.age = currentYear - year;
}
};
// 访问dataproperty
console.log(person.name); // 张三
// 访问访问器property (getter)
console.log(person.fullInfo); // 张三, 30岁, 男
// 设置访问器property (setter)
person.birthYear = 1990;
console.log(person.age); // 34 (fake设当 before 年份 is 2024)
3.2 method
method is object functionproperty, 用于定义object behavior:
const person = {
name: "张三",
age: 30,
// method
greet: function() {
console.log(`你 good , 我 is ${this.name}!`);
},
// 箭头functionserving asmethod (注意: 箭头function没 has 自己 this)
getAge: () => {
return this.age; // 这里 this不指向personobject
},
// 简写method (ES6+)
celebrateBirthday() {
this.age++;
console.log(`生日 fast 乐!现 in 我${this.age}岁了. `);
}
};
// 调用method
person.greet(); // 你 good , 我 is 张三!
person.celebrateBirthday(); // 生日 fast 乐!现 in 我31岁了.
4. object 访问 and modify
可以through点表示法 or 方括号表示法访问 and modifyobject property and method.
4.1 访问property
const person = {
name: "张三",
age: 30,
"full name": "张三全", // package含空格 property名
greet: function() {
console.log(`你 good , 我 is ${this.name}!`);
}
};
// 点表示法 (推荐)
console.log(person.name); // 张三
person.greet(); // 你 good , 我 is 张三!
// 方括号表示法 (用于特殊property名)
console.log(person["age"]); // 30
console.log(person["full name"]); // 张三全
// usingvariable访问property
const propertyName = "name";
console.log(person[propertyName]); // 张三
4.2 modifyproperty
const person = {
name: "张三",
age: 30
};
// modify现 has property
person.age = 31;
console.log(person.age); // 31
// 添加 new property
person.gender = "男";
console.log(person.gender); // 男
// 添加 new method
person.greet = function() {
console.log(`你 good , 我 is ${this.name}!`);
};
person.greet(); // 你 good , 我 is 张三!
// using方括号添加property
person["email"] = "zhangsan@example.com";
console.log(person.email); // zhangsan@example.com
4.3 deleteproperty
usingdelete运算符deleteobject property:
const person = {
name: "张三",
age: 30,
gender: "男"
};
console.log(person.gender); // 男
// deleteproperty
delete person.gender;
console.log(person.gender); // undefined
// delete不存 in property (不会报错)
delete person.email;
console.log(person.email); // undefined
5. object 遍历
可以using many 种method遍历object property and 值: for...in循环, Object.keys(), Object.values(), Object.entries()etc..
5.1 for...in循环
遍历object 可枚举property (includinginheritance property) :
const person = {
name: "张三",
age: 30,
gender: "男"
};
// usingfor...in循环遍历
for (let key in person) {
console.log(`${key}: ${person[key]}`);
}
// 输出:
// name: 张三
// age: 30
// gender: 男
5.2 Object.keys(), Object.values(), Object.entries()
ES6引入 method, 用于获取object 键, 值 or 键值 for :
const person = {
name: "张三",
age: 30,
gender: "男"
};
// 获取所 has 键
const keys = Object.keys(person);
console.log(keys); // ["name", "age", "gender"]
// 获取所 has 值
const values = Object.values(person);
console.log(values); // ["张三", 30, "男"]
// 获取所 has 键值 for
const entries = Object.entries(person);
console.log(entries); // [["name", "张三"], ["age", 30], ["gender", "男"]]
// usingforEach遍历键值 for
entries.forEach(([key, value]) => {
console.log(`${key}: ${value}`);
});
// 输出:
// name: 张三
// age: 30
// gender: 男
5.3 Object.getOwnPropertyNames()
获取object 所 has property名 (including不可枚举property) :
const person = {
name: "张三",
age: 30
};
// 添加一个不可枚举property
Object.defineProperty(person, "gender", {
value: "男",
enumerable: false
});
// 获取所 has property名 (including不可枚举)
const properties = Object.getOwnPropertyNames(person);
console.log(properties); // ["name", "age", "gender"]
// Object.keys()只返回可枚举property
const enumerableProperties = Object.keys(person);
console.log(enumerableProperties); // ["name", "age"]
6. object inheritance
JavaScriptusing原型链implementationinheritance, 每个object都 has 一个原型object, inheritance原型object property and method.
6.1 原型链
原型链 is JavaScriptimplementationinheritance mechanism, object可以through原型链访问其原型object property and method:
// 原型object
const animal = {
eat: function() {
console.log("吃东西");
}
};
// creationinheritanceanimal object
const dog = Object.create(animal);
dog.bark = function() {
console.log("汪汪汪");
};
// creationinheritancedog object
const goldenRetriever = Object.create(dog);
goldenRetriever.name = "金毛";
// 访问自己 property
console.log(goldenRetriever.name); // 金毛
// 访问dog method
goldenRetriever.bark(); // 汪汪汪
// 访问animal method
goldenRetriever.eat(); // 吃东西
// check原型链
console.log(Object.getPrototypeOf(goldenRetriever) === dog); // true
console.log(Object.getPrototypeOf(dog) === animal); // true
console.log(Object.getPrototypeOf(animal) === Object.prototype); // true
console.log(Object.getPrototypeOf(Object.prototype) === null); // true
6.2 constructfunctioninheritance
usingconstructfunction and 原型implementationinheritance:
// 父constructfunction
function Animal(name) {
this.name = name;
}
// 父constructfunction 原型method
Animal.prototype.eat = function() {
console.log(`${this.name} in 吃东西`);
};
// 子constructfunction
function Dog(name, breed) {
// 调用父constructfunction
Animal.call(this, name);
this.breed = breed;
}
// 设置子constructfunction 原型
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
// 子constructfunction 原型method
Dog.prototype.bark = function() {
console.log(`${this.name} in 汪汪汪`);
};
// creationinstance
const dog = new Dog(" small 黑", "拉布拉 many ");
// 访问inheritance property and method
dog.eat(); // small 黑 in 吃东西
dog.bark(); // small 黑 in 汪汪汪
console.log(dog.name); // small 黑
console.log(dog.breed); // 拉布拉 many
// checkinstancerelationships
console.log(dog instanceof Dog); // true
console.log(dog instanceof Animal); // true
6.3 classinheritance (ES6+)
ES6引入了classinheritance语法, usingextends关键字:
// 父class
class Animal {
constructor(name) {
this.name = name;
}
eat() {
console.log(`${this.name} in 吃东西`);
}
}
// 子class
class Dog extends Animal {
constructor(name, breed) {
super(name); // 调用父classconstructfunction
this.breed = breed;
}
bark() {
console.log(`${this.name} in 汪汪汪`);
}
}
// 孙子class
class GoldenRetriever extends Dog {
constructor(name) {
super(name, "金毛"); // 调用父classconstructfunction
}
fetch() {
console.log(`${this.name} in 捡球`);
}
}
// creationinstance
const dog = new GoldenRetriever(" small 白");
// 访问inheritance property and method
dog.eat(); // small 白 in 吃东西
dog.bark(); // small 白 in 汪汪汪
dog.fetch(); // small 白 in 捡球
console.log(dog.name); // small 白
console.log(dog.breed); // 金毛
// checkinstancerelationships
console.log(dog instanceof GoldenRetriever); // true
console.log(dog instanceof Dog); // true
console.log(dog instanceof Animal); // true
7. this关键字
this is JavaScriptin 特殊关键字, 指向当 before 执行 on under 文 object. this 值取决于function 调用方式.
7.1 this 指向
// 1. 全局 on under 文
console.log(this); // 浏览器in指向windowobject, Node.jsin指向globalobject
// 2. function调用
function sayHello() {
console.log(`Hello, ${this.name}!`);
}
const person = { name: "张三" };
sayHello(); // Hello, undefined! (this指向全局object)
// 3. method调用
const person = {
name: "张三",
greet: function() {
console.log(`你 good , 我 is ${this.name}!`);
}
};
person.greet(); // 你 good , 我 is 张三! (this指向personobject)
// 4. constructfunction调用
function Person(name) {
this.name = name;
console.log(`creation了一个名 for ${this.name} 人`);
}
const p = new Person("李四"); // creation了一个名 for 李四 人 (this指向 new creation object)
// 5. call() and apply()调用
function greet() {
console.log(`你 good , 我 is ${this.name}!`);
}
const person1 = { name: "王五" };
greet.call(person1); // 你 good , 我 is 王五! (this指向person1object)
// 6. bind()调用
const boundGreet = greet.bind({ name: "赵六" });
boundGreet(); // 你 good , 我 is 赵六! (this指向绑定 object)
// 7. 箭头functionin this
const person = {
name: "张三",
greet: function() {
// 箭头functioninheritance out 层作用域 this
const sayHello = () => {
console.log(`你 good , 我 is ${this.name}!`);
};
sayHello();
}
};
person.greet(); // 你 good , 我 is 张三! (箭头function this指向personobject)
8. object advanced features
8.1 object propertydescribes符
propertydescribes符用于describesobjectproperty features, including值, 可写性, 可枚举性 and 可configuration性:
// creationobject
const person = {};
// usingObject.defineProperty()定义property
Object.defineProperty(person, "name", {
value: "张三",
writable: true, // 可写
enumerable: true, // 可枚举
configurable: true // 可configuration
});
Object.defineProperty(person, "age", {
value: 30,
writable: false, // 不可写
enumerable: false, // 不可枚举
configurable: true
});
console.log(person.name); // 张三
console.log(person.age); // 30
// 尝试modify不可写property
person.age = 31;
console.log(person.age); // 30 (未被modify)
// 枚举property
console.log(Object.keys(person)); // ["name"] (age不可枚举)
// usingObject.defineProperties()定义 many 个property
Object.defineProperties(person, {
gender: {
value: "男",
writable: true
},
email: {
value: "zhangsan@example.com",
writable: true
}
});
console.log(person.gender); // 男
8.2 object 冻结, 密封 and 防scale
JavaScriptproviding了method来限制object modify:
// 1. Object.preventExtensions(): 防止添加 new property
const person = { name: "张三", age: 30 };
Object.preventExtensions(person);
person.gender = "男";
console.log(person.gender); // undefined (无法添加 new property)
// 2. Object.seal(): 防止添加 and deleteproperty, 但可以modify现 has property
const person = { name: "张三", age: 30 };
Object.seal(person);
person.age = 31; // 可以modify现 has property
console.log(person.age); // 31
person.gender = "男"; // 无法添加 new property
console.log(person.gender); // undefined
delete person.name; // 无法deleteproperty
console.log(person.name); // 张三
// 3. Object.freeze(): 防止添加, delete and modifyproperty
const person = { name: "张三", age: 30 };
Object.freeze(person);
person.age = 31; // 无法modify现 has property
console.log(person.age); // 30
person.gender = "男"; // 无法添加 new property
console.log(person.gender); // undefined
delete person.name; // 无法deleteproperty
console.log(person.name); // 张三
// checkobjectstatus
console.log(Object.isExtensible(person)); // false
console.log(Object.isSealed(person)); // true
console.log(Object.isFrozen(person)); // true
8.3 object merge
可以usingObject.assign() or unfold运算符 (ES6+) mergeobject:
// 1. Object.assign()
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 };
const obj3 = { d: 5 };
const merged = Object.assign({}, obj1, obj2, obj3);
console.log(merged); // { a: 1, b: 3, c: 4, d: 5 } ( after 面 object会覆盖 before 面 同名property)
// 2. unfold运算符 (ES6+)
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 };
const obj3 = { d: 5 };
const merged = { ...obj1, ...obj2, ...obj3 };
console.log(merged); // { a: 1, b: 3, c: 4, d: 5 }
// 3. 深度merge
const deepMerge = (target, ...sources) => {
if (!sources.length) return target;
const source = sources.shift();
for (const key in source) {
if (source.hasOwnProperty(key)) {
if (source[key] && typeof source[key] === 'object') {
if (!target[key]) target[key] = {};
deepMerge(target[key], source[key]);
} else {
target[key] = source[key];
}
}
}
return deepMerge(target, ...sources);
};
const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { b: { d: 3 }, e: 4 };
const merged = deepMerge({}, obj1, obj2);
console.log(merged); // { a: 1, b: { c: 2, d: 3 }, e: 4 }
实践case: objectapplication
creation一个JavaScript程序, usingobjectimplementation以 under functions:
- creation一个
Calculatorobject, package含加, 减, 乘, 除method - creation一个
Personclass, package含姓名, 年龄property, 以及问候method - creation一个
Studentclass, inheritance自Personclass, 添加学号, 专业property, 以及Learningmethod - creation一个toolobject
Utils, package含日期format, array去重etc.静态method - test所 has object and class functions
// 实践case: objectapplication
// 1. Calculatorobject
const Calculator = {
add: function(a, b) {
return a + b;
},
subtract: function(a, b) {
return a - b;
},
multiply: function(a, b) {
return a * b;
},
divide: function(a, b) {
if (b === 0) {
return 'error: 除数不能 for 零';
}
return a / b;
}
};
// 2. Personclass
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log(`你 good , 我 is ${this.name}, 今年${this.age}岁. `);
}
celebrateBirthday() {
this.age++;
console.log(`生日 fast 乐!现 in 我${this.age}岁了. `);
}
}
// 3. Studentclass (inheritance自Person)
class Student extends Person {
constructor(name, age, studentId, major) {
super(name, age);
this.studentId = studentId;
this.major = major;
}
study() {
console.log(`${this.name}正 in Learning${this.major}专业 课程. `);
}
// 重写父classmethod
greet() {
console.log(`你 good , 我 is ${this.name}, 今年${this.age}岁, 学号 is ${this.studentId}, 专业 is ${this.major}. `);
}
}
// 4. Utilstoolobject
const Utils = {
// 日期format
formatDate: function(date) {
const d = new Date(date);
const year = d.getFullYear();
const month = String(d.getMonth() + 1).padStart(2, '0');
const day = String(d.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
},
// array去重
uniqueArray: function(arr) {
return [...new Set(arr)];
},
// 深拷贝object
deepClone: function(obj) {
return JSON.parse(JSON.stringify(obj));
},
// 随机数生成
randomNumber: function(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
};
// 5. test
console.log('=== testCalculator ===');
console.log('3 + 5 =', Calculator.add(3, 5)); // 8
console.log('10 - 4 =', Calculator.subtract(10, 4)); // 6
console.log('6 * 7 =', Calculator.multiply(6, 7)); // 42
console.log('20 / 5 =', Calculator.divide(20, 5)); // 4
console.log('\n=== testPerson ===');
const person = new Person('张三', 30);
person.greet(); // 你 good , 我 is 张三, 今年30岁.
person.celebrateBirthday(); // 生日 fast 乐!现 in 我31岁了.
console.log('\n=== testStudent ===');
const student = new Student('李四', 20, '2024001', '计算机科学');
student.greet(); // 你 good , 我 is 李四, 今年20岁, 学号 is 2024001, 专业 is 计算机科学.
student.study(); // 李四正 in Learning计算机科学专业 课程.
student.celebrateBirthday(); // 生日 fast 乐!现 in 我21岁了.
console.log('\n=== testUtils ===');
console.log('日期format:', Utils.formatDate(new Date())); // 例such as: 2024-01-06
console.log('array去重:', Utils.uniqueArray([1, 2, 2, 3, 4, 4, 5])); // [1, 2, 3, 4, 5]
const original = { a: 1, b: { c: 2 } };
const cloned = Utils.deepClone(original);
console.log('深拷贝object:', cloned); // { a: 1, b: { c: 2 } }
console.log('随机数(1-10):', Utils.randomNumber(1, 10)); // 1-10之间 随机数
互动练习: objectchallenges
Movieclass, package含以 under property and method: - property: 标题, 导演, 年份, 评分
- method: 获取电影information, update评分
- 静态method: 比较两部电影 评分
Libraryobject, management电影collection: - method: 添加电影, delete电影, find电影, 获取所 has 电影
- usingarraystore电影object
Personobject, 演示this 不同指向: - using普通function, 箭头function and method
- 演示
call(),apply()andbind()method
deepCompare, 深度比较两个object is 否相etc.: - processing嵌套object and array
- 返回boolean值表示 is 否相etc.
9. objectbest practices
9.1 命名规范
- using驼峰命名法命名object, property and method
- usingdescribes性 名称, 清晰表达object 用途
- for 于constructfunction and class, using首字母 big 写 帕斯卡命名法
9.2 objectdesign
- object应该 has 单一 职责, 只package含相关 property and method
- usingclass and inheritance组织相关 objectclass型
- usinggetter and setter控制property 访问 and modify
- 避免using全局objectstorestatus
9.3 performance考虑
- for 于频繁creation object, 考虑usingobject池
- 避免 in 循环increationobject
- using
Object.create(null)creation没 has 原型 object, improvingfind速度 - for 于 big 型object, 考虑usingMap or Setdatastructure