1.2.1 Object类型
概念解释
- 定义:键值对的集合,用于存储相关数据和功能
- 特点:引用类型、可动态添加属性和方法
- 使用场景:数据封装、配置对象、原型继承
详细说明
1. 对象的创建和基本操作
const user1 = {
name: '张三',
age: 25,
sayHi() {
console.log(`Hi, I'm ${this.name}`);
}
};
function User(name, age) {
this.name = name;
this.age = age;
}
const user2 = new User('李四', 30);
const user3 = Object.create(null);
const user4 = Object.create(Object.prototype);
function createUser(name, age) {
return {
name,
age,
sayHi() {
console.log(`Hi, I'm ${this.name}`);
}
};
}
2. 属性描述符和对象特性
const person = {};
Object.defineProperty(person, 'name', {
value: '张三',
writable: true,
enumerable: true,
configurable: true
});
let _age = 25;
Object.defineProperty(person, 'age', {
get() {
return _age;
},
set(value) {
if (value < 0) throw new Error('年龄不能为负数');
_age = value;
},
enumerable: true,
configurable: true
});
const config = {
apiKey: 'abc123',
endpoint: 'https://api.example.com'
};
Object.freeze(config);
Object.seal(config);
Object.preventExtensions(config);
console.log(Object.isFrozen(config));
console.log(Object.isSealed(config));
console.log(Object.isExtensible(config));
3. 对象操作和遍历
const obj = {
a: 1,
b: 2,
'special-key': 3
};
console.log(obj.a);
console.log(obj['special-key']);
console.log('a' in obj);
console.log(obj.hasOwnProperty('a'));
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
console.log(`${key}: ${obj[key]}`);
}
}
console.log(Object.keys(obj));
console.log(Object.values(obj));
console.log(Object.entries(obj));
const clone1 = Object.assign({}, obj);
const clone2 = { ...obj };
function deepClone(obj) {
if (obj === null || typeof obj !== 'object') return obj;
const clone = Array.isArray(obj) ? [] : {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
clone[key] = deepClone(obj[key]);
}
}
return clone;
}
4. 现代JavaScript对象特性
const { name, age = 20, address: { city } = {} } = user;
const x = 1, y = 2;
const point = { x, y };
const prefix = 'user';
const users = {
[`${prefix}1`]: '张三',
[`${prefix}2`]: '李四'
};
const calculator = {
add(a, b) {
return a + b;
},
subtract(a, b) {
return a - b;
}
};
const response = {
data: {
user: {
address: null
}
}
};
const city = response?.data?.user?.address?.city ?? 'Unknown';
5. 实际应用模式
function initializeApp(config) {
const defaultConfig = {
debug: false,
timeout: 3000,
retries: 3
};
return {
...defaultConfig,
...config
};
}
function createCounter() {
let count = 0;
return {
increment() {
return ++count;
},
decrement() {
return --count;
},
getCount() {
return count;
}
};
}
class EventEmitter {
#listeners = new Map();
on(event, callback) {
if (!this.#listeners.has(event)) {
this.#listeners.set(event, new Set());
}
this.#listeners.get(event).add(callback);
}
emit(event, ...args) {
const callbacks = this.#listeners.get(event);
if (callbacks) {
for (const callback of callbacks) {
callback(...args);
}
}
}
off(event, callback) {
const callbacks = this.#listeners.get(event);
if (callbacks) {
callbacks.delete(callback);
}
}
}
6. 性能优化和最佳实践
class UserManager {
#userCache = new Map();
getUser(id) {
if (this.#userCache.has(id)) {
return this.#userCache.get(id);
}
const user = this.fetchUser(id);
this.#userCache.set(id, user);
return user;
}
}
class ObjectPool {
#available = [];
#inUse = new Set();
acquire() {
let obj = this.#available.pop();
if (!obj) {
obj = this.createObject();
}
this.#inUse.add(obj);
return obj;
}
release(obj) {
if (this.#inUse.delete(obj)) {
this.resetObject(obj);
this.#available.push(obj);
}
}
createObject() {
}
resetObject(obj) {
}
}
class ConfigManager {
#config = {};
constructor(initialConfig) {
Object.defineProperties(this.#config, {
apiKey: {
value: initialConfig.apiKey,
writable: false,
enumerable: true
},
debug: {
value: initialConfig.debug,
writable: true,
enumerable: true
}
});
}
}
1.2.2 Array类型
概念解释
- 定义:有序的数据集合
- 特点:动态长度、支持多种数据类型、丰富的内置方法
- 使用场景:数据列表、队列/栈、数据处理
详细说明
1. 数组的创建和基本操作
const arr1 = [1, 2, 3];
const arr2 = new Array(3);
const arr3 = new Array(1, 2, 3);
const arr4 = Array.from('hello');
const arr5 = Array.from({length: 5}, (_, i) => i * 2);
const arr6 = Array.of(3);
const arr7 = Array.of(1, 2, 3);
const numbers = [1, 2, 3, 4, 5];
console.log(numbers[0]);
console.log(numbers.at(-1));
numbers[0] = 10;
numbers.push(6);
numbers.unshift(0);
const last = numbers.pop();
const first = numbers.shift();
2. 数组高级操作和方法
const arr = [1, 2, 3, 4, 5];
const doubled = arr.map(x => x * 2);
const evenNumbers = arr.filter(x => x % 2 === 0);
const sum = arr.reduce((acc, curr) => acc + curr, 0);
const max = arr.reduce((a, b) => Math.max(a, b));
const found = arr.find(x => x > 3);
const foundIndex = arr.findIndex(x => x > 3);
const hasEven = arr.some(x => x % 2 === 0);
const allPositive = arr.every(x => x > 0);
const original = [1, 2, 3, 4, 5];
const slice1 = original.slice(1, 3);
const slice2 = original.slice(-2);
const spliced = [...original];
spliced.splice(1, 2, 'a', 'b');
console.log(spliced);
const combined = [0, ...original, 6];
3. 数组排序和搜索
const numbers = [23, 5, 100, 56, 9, 13];
const strings = ['banana', 'apple', 'Cherry', 'date'];
numbers.sort((a, b) => a - b);
numbers.sort((a, b) => b - a);
strings.sort((a, b) => a.localeCompare(b));
class SortUtils {
static quickSort(arr) {
if (arr.length <= 1) return arr;
const pivot = arr[Math.floor(arr.length / 2)];
const left = arr.filter(x => x < pivot);
const middle = arr.filter(x => x === pivot);
const right = arr.filter(x => x > pivot);
return [...this.quickSort(left), ...middle, ...this.quickSort(right)];
}
static mergeSort(arr) {
if (arr.length <= 1) return arr;
const mid = Math.floor(arr.length / 2);
const left = this.mergeSort(arr.slice(0, mid));
const right = this.mergeSort(arr.slice(mid));
return this.merge(left, right);
}
static merge(left, right) {
const result = [];
let i = 0, j = 0;
while (i < left.length && j < right.length) {
result.push(left[i] <= right[j] ? left[i++] : right[j++]);
}
return [...result, ...left.slice(i), ...right.slice(j)];
}
}
4. 数组性能优化和最佳实践
const n = 1000000;
const arr = new Array(n);
class ArrayOptimization {
static badPractice(arr) {
for (let i = 0; i < 1000; i++) {
arr.unshift(i);
}
}
static goodPractice(arr) {
const temp = new Array(1000);
for (let i = 0; i < 1000; i++) {
temp[i] = i;
}
return [...temp, ...arr];
}
static useTypedArray() {
const int32Arr = new Int32Array(1000);
const float64Arr = new Float64Array(1000);
return {
int32Arr,
float64Arr
};
}
}
class ArrayDeduplication {
static usingSet(arr) {
return [...new Set(arr)];
}
static usingMap(arr) {
return Array.from(new Map(arr.map(item => [
typeof item === 'object' ? JSON.stringify(item) : item,
item
])).values());
}
}
5. 实际应用场景
class Pagination {
static paginate(array, pageSize, pageNumber) {
return array.slice(
(pageNumber - 1) * pageSize,
pageNumber * pageSize
);
}
static createPageInfo(array, pageSize) {
return {
totalItems: array.length,
totalPages: Math.ceil(array.length / pageSize),
hasNextPage: (pageNumber) =>
pageNumber * pageSize < array.length,
hasPrevPage: (pageNumber) => pageNumber > 1
};
}
}
class DataProcessor {
static groupBy(array, key) {
return array.reduce((groups, item) => {
const group = groups[item[key]] || [];
return {
...groups,
[item[key]]: [...group, item]
};
}, {});
}
static flatten(array, depth = 1) {
return array.reduce((flat, item) => {
return flat.concat(
Array.isArray(item) && depth > 0
? this.flatten(item, depth - 1)
: item
);
}, []);
}
}
class ArrayCache {
#cache = new Map();
#maxSize;
constructor(maxSize = 1000) {
this.#maxSize = maxSize;
}
set(key, value) {
if (this.#cache.size >= this.#maxSize) {
const firstKey = this.#cache.keys().next().value;
this.#cache.delete(firstKey);
}
this.#cache.set(key, value);
}
get(key) {
return this.#cache.get(key);
}
}
1.2.3 Function类型
概念解释
- 定义:可执行的代码块,也是一种特殊的对象
- 特点:一等公民、支持闭包、动态this绑定
- 使用场景:代码复用、回调、面向对象编程、函数式编程
详细说明
1. 函数的创建和基本特性
function add(a, b) {
return a + b;
}
const subtract = function(a, b) {
return a - b;
};
const multiply = (a, b) => a * b;
const divide = new Function('a', 'b', 'return a / b');
function example(required, optional = 'default', ...rest) {
console.log(required);
console.log(optional);
console.log(rest);
}
function greet(name) {
console.log(`Hello, ${name}!`);
}
console.log(greet.length);
console.log(greet.name);
console.log(greet.toString());
2. 闭包和作用域
function createCounter() {
let count = 0;
return {
increment() {
return ++count;
},
decrement() {
return --count;
},
getCount() {
return count;
}
};
}
const calculator = (function() {
let result = 0;
function validate(n) {
return typeof n === 'number' && !isNaN(n);
}
return {
add(n) {
if (validate(n)) result += n;
return this;
},
subtract(n) {
if (validate(n)) result -= n;
return this;
},
getResult() {
return result;
}
};
})();
function memoize(fn) {
const cache = new Map();
return function(...args) {
const key = JSON.stringify(args);
if (cache.has(key)) {
return cache.get(key);
}
const result = fn.apply(this, args);
cache.set(key, result);
return result;
};
}
const memoizedFib = memoize(function fib(n) {
if (n <= 1) return n;
return fib(n - 1) + fib(n - 2);
});
3. this绑定和上下文
class ThisBindingDemo {
constructor() {
this.value = 42;
}
regularMethod() {
console.log(this.value);
}
arrowMethod = () => {
console.log(this.value);
}
static demonstrateBinding() {
const obj = { value: 'test' };
function fn() {
console.log(this.value);
}
fn.call(obj);
fn.apply(obj, []);
const boundFn = fn.bind(obj);
boundFn();
}
}
class ContextPreservation {
constructor() {
this.data = [1, 2, 3];
}
badAsyncOperation() {
this.data.forEach(function(item) {
setTimeout(function() {
console.log(this.data);
}, 100);
});
}
goodAsyncOperation() {
this.data.forEach(item => {
setTimeout(() => {
console.log(this.data);
}, 100);
});
}
}
4. 函数式编程特性
class FunctionalProgramming {
static compose(...fns) {
return fns.reduce((f, g) => (...args) => f(g(...args)));
}
static curry(fn) {
return function curried(...args) {
if (args.length >= fn.length) {
return fn.apply(this, args);
}
return (...moreArgs) => curried.apply(this, [...args, ...moreArgs]);
};
}
static partial(fn, ...presetArgs) {
return function(...laterArgs) {
return fn.apply(this, [...presetArgs, ...laterArgs]);
};
}
}
const pipe = (...fns) => x => fns.reduce((v, f) => f(v), x);
const processData = pipe(
x => x * 2,
x => x + 1,
x => x.toString()
);
const users = [
{ id: 1, name: 'John', age: 30 },
{ id: 2, name: 'Jane', age: 25 },
{ id: 3, name: 'Bob', age: 35 }
];
const processUsers = pipe(
users => users.filter(u => u.age > 25),
users => users.map(u => u.name),
names => names.join(', ')
);
5. 性能优化和最佳实践
class FunctionOptimization {
static debounce(fn, delay) {
let timeoutId;
return function(...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => fn.apply(this, args), delay);
};
}
static throttle(fn, limit) {
let inThrottle;
return function(...args) {
if (!inThrottle) {
fn.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
static reuseFunction() {
const badExample = {
handleClick: () => console.log('clicked'),
render() {
return {
onClick: () => console.log('clicked')
};
}
};
const goodExample = {
handleClick: () => console.log('clicked'),
render() {
return {
onClick: this.handleClick
};
}
};
}
}
class AsyncFunctionHandling {
static async asyncWrapper(fn) {
try {
const result = await fn();
return [null, result];
} catch (error) {
return [error, null];
}
}
static async retry(fn, attempts = 3, delay = 1000) {
for (let i = 0; i < attempts; i++) {
try {
return await fn();
} catch (error) {
if (i === attempts - 1) throw error;
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
}
6. 实际应用场景
class EventSystem {
#handlers = new Map();
on(event, handler) {
if (!this.#handlers.has(event)) {
this.#handlers.set(event, new Set());
}
this.#handlers.get(event).add(handler);
return () => this.off(event, handler);
}
off(event, handler) {
const handlers = this.#handlers.get(event);
if (handlers) {
handlers.delete(handler);
}
}
emit(event, ...args) {
const handlers = this.#handlers.get(event);
if (handlers) {
handlers.forEach(handler => handler(...args));
}
}
}
class MiddlewareSystem {
#middlewares = [];
use(middleware) {
this.#middlewares.push(middleware);
return this;
}
async execute(context) {
const runner = this.#middlewares.reduceRight(
(next, middleware) => async () => {
await middleware(context, next);
},
async () => {}
);
await runner();
}
}