JavaScript 對象說明

JavaScript 對象說明

1. 對象的基本概念

在 JavaScript 中,對象是一種復合數據類型,用于存儲相關聯的屬性和方法。對象可以看作是屬性的集合,其中每個屬性都由一個鍵(key)和一個值(value)組成。值可以是任何 JavaScript 數據類型,包括數字、字符串、布爾值、數組、函數,甚至是其他對象。

JavaScript 對象具有以下特點:

  • 是一種引用數據類型
  • 具有動態特性,可以隨時添加、修改或刪除屬性
  • 支持原型繼承
  • 可以通過多種方式創建

2. 創建對象的方法

2.1 對象字面量

對象字面量是創建對象最常用和最簡潔的方法,使用花括號 {} 定義。

// 空對象
const emptyObject = {};// 包含屬性的對象
const person = {name: "張三",age: 30,isStudent: false,hobbies: ["閱讀", "編程", "旅行"],address: {city: "北京",district: "朝陽區"},sayHello: function() {console.log(`你好,我是${this.name}`);}
};

2.2 使用 new Object() 構造函數

const person = new Object();
person.name = "張三";
person.age = 30;
person.sayHello = function() {console.log(`你好,我是${this.name}`);
};

2.3 使用 Object.create() 方法

Object.create() 方法創建一個新對象,使用現有的對象作為新對象的原型。

// 創建一個原型對象
const personPrototype = {sayHello: function() {console.log(`你好,我是${this.name}`);}
};// 使用原型對象創建新對象
const person = Object.create(personPrototype);
person.name = "張三";
person.age = 30;

2.4 構造函數模式

使用構造函數可以創建多個具有相同屬性和方法的對象實例。

// 定義構造函數
function Person(name, age) {this.name = name;this.age = age;this.sayHello = function() {console.log(`你好,我是${this.name}`);};
}// 使用 new 關鍵字創建對象實例
const person1 = new Person("張三", 30);
const person2 = new Person("李四", 25);

2.5 原型模式

將方法定義在構造函數的原型上,可以讓所有實例共享這些方法,節省內存。

// 定義構造函數
function Person(name, age) {this.name = name;this.age = age;
}// 在原型上定義方法
Person.prototype.sayHello = function() {console.log(`你好,我是${this.name}`);
};// 創建對象實例
const person1 = new Person("張三", 30);
const person2 = new Person("李四", 25);

2.6 ES6 類語法

ES6 引入了類(class)語法,提供了更接近傳統面向對象語言的語法糖,但底層仍然基于原型。

// 使用 class 定義類
class Person {constructor(name, age) {this.name = name;this.age = age;}sayHello() {console.log(`你好,我是${this.name}`);}
}// 創建類的實例
const person = new Person("張三", 30);

3. 對象的屬性操作

3.1 訪問對象屬性

有兩種方式可以訪問對象的屬性:點表示法(.)和方括號表示法([])。

const person = {name: "張三",age: 30,"full-name": "張三先生"
};// 點表示法
console.log(person.name); // 輸出: 張三// 方括號表示法
console.log(person["age"]); // 輸出: 30
console.log(person["full-name"]); // 輸出: 張三先生 (適用于包含特殊字符的屬性名)// 使用變量作為屬性名
const prop = "name";
console.log(person[prop]); // 輸出: 張三

3.2 添加新屬性

可以隨時為對象添加新屬性。

const person = {name: "張三",age: 30
};// 添加新屬性
person.email = "zhangsan@example.com";
person["phone"] = "13800138000";console.log(person);
// 輸出: { name: '張三', age: 30, email: 'zhangsan@example.com', phone: '13800138000' }

3.3 修改屬性值

const person = {name: "張三",age: 30
};// 修改屬性值
person.age = 31;
person["name"] = "張三豐";console.log(person);
// 輸出: { name: '張三豐', age: 31 }

3.4 刪除屬性

使用 delete 操作符可以刪除對象的屬性。

const person = {name: "張三",age: 30,email: "zhangsan@example.com"
};// 刪除屬性
delete person.email;console.log(person);
// 輸出: { name: '張三', age: 30 }
console.log(person.email); // 輸出: undefined

3.5 檢查屬性是否存在

使用 in 操作符或 hasOwnProperty() 方法可以檢查對象是否包含特定屬性。

const person = {name: "張三",age: 30
};// 使用 in 操作符
console.log("name" in person); // 輸出: true
console.log("email" in person); // 輸出: false// 使用 hasOwnProperty() 方法
console.log(person.hasOwnProperty("name")); // 輸出: true
console.log(person.hasOwnProperty("toString")); // 輸出: false (toString 是原型鏈上的方法)

4. 對象的方法

4.1 定義方法

方法是存儲在對象屬性中的函數。

const calculator = {add: function(a, b) {return a + b;},subtract: function(a, b) {return a - b;},// ES6 簡寫語法multiply(a, b) {return a * b;},divide(a, b) {if (b === 0) {return "除數不能為零";}return a / b;}
};console.log(calculator.add(5, 3)); // 輸出: 8
console.log(calculator.multiply(5, 3)); // 輸出: 15

4.2 this 關鍵字

在對象方法中,this 指向調用該方法的對象。

const person = {name: "張三",age: 30,sayHello: function() {console.log(`你好,我是${this.name},今年${this.age}歲。`);},birthday: function() {this.age += 1;console.log(`${this.name}生日快樂!現在${this.age}歲了。`);}
};person.sayHello(); // 輸出: 你好,我是張三,今年30歲。
person.birthday(); // 輸出: 張三生日快樂!現在31歲了。

4.3 箭頭函數與 this

注意:在箭頭函數中,this 不綁定到調用該函數的對象,而是繼承自外層作用域。

const person = {name: "張三",age: 30,// 普通函數,this 指向 person 對象sayHello: function() {console.log(`你好,我是${this.name}`);},// 箭頭函數,this 不指向 person 對象greet: () => {console.log(`你好,我是${this.name}`); // 這里的 this 可能是全局對象或 undefined(嚴格模式下)}
};person.sayHello(); // 輸出: 你好,我是張三。
person.greet(); // 輸出: 你好,我是undefined。(瀏覽器環境中可能顯示為空)

5. 對象的遍歷

5.1 for…in 循環

for...in 循環可以遍歷對象的所有可枚舉屬性(包括繼承的屬性)。

const person = {name: "張三",age: 30,email: "zhangsan@example.com"
};// 遍歷對象的所有可枚舉屬性
for (let key in person) {// 通常使用 hasOwnProperty() 過濾掉繼承的屬性if (person.hasOwnProperty(key)) {console.log(`${key}: ${person[key]}`);}
}
// 輸出:
// name: 張三
// age: 30
// email: zhangsan@example.com

5.2 Object.keys()

Object.keys() 方法返回一個包含對象自身所有可枚舉屬性名稱的數組。

const person = {name: "張三",age: 30,email: "zhangsan@example.com"
};const keys = Object.keys(person);
console.log(keys); // 輸出: [ 'name', 'age', 'email' ]// 使用 forEach 遍歷
keys.forEach(key => {console.log(`${key}: ${person[key]}`);
});

5.3 Object.values()

Object.values() 方法返回一個包含對象自身所有可枚舉屬性值的數組。

const person = {name: "張三",age: 30,email: "zhangsan@example.com"
};const values = Object.values(person);
console.log(values); // 輸出: [ '張三', 30, 'zhangsan@example.com' ]

5.4 Object.entries()

Object.entries() 方法返回一個包含對象自身所有可枚舉屬性的鍵值對數組。

const person = {name: "張三",age: 30,email: "zhangsan@example.com"
};const entries = Object.entries(person);
console.log(entries);
// 輸出: [ [ 'name', '張三' ], [ 'age', 30 ], [ 'email', 'zhangsan@example.com' ] ]// 使用 for...of 遍歷
for (let [key, value] of entries) {console.log(`${key}: ${value}`);
}

6. 對象的高級特性

6.1 對象解構賦值

ES6 引入了對象解構賦值,可以從對象中提取屬性并賦值給變量。

const person = {name: "張三",age: 30,email: "zhangsan@example.com",address: {city: "北京",district: "朝陽區"}
};// 基本解構賦值
const { name, age } = person;
console.log(name); // 輸出: 張三
console.log(age); // 輸出: 30// 重命名變量
const { name: fullName, email: contactEmail } = person;
console.log(fullName); // 輸出: 張三
console.log(contactEmail); // 輸出: zhangsan@example.com// 默認值
const { phone = "未知" } = person;
console.log(phone); // 輸出: 未知// 嵌套對象解構
const { address: { city, district } } = person;
console.log(city); // 輸出: 北京
console.log(district); // 輸出: 朝陽區

6.2 對象展開運算符

ES6 引入了展開運算符(...),可以用于復制對象屬性或合并對象。

const person1 = {name: "張三",age: 30
};// 復制對象
const person2 = { ...person1 };
console.log(person2); // 輸出: { name: '張三', age: 30 }// 合并對象
const contactInfo = {email: "zhangsan@example.com",phone: "13800138000"
};const completePerson = { ...person1, ...contactInfo };
console.log(completePerson);
// 輸出: { name: '張三', age: 30, email: 'zhangsan@example.com', phone: '13800138000' }// 覆蓋屬性
const updatedPerson = { ...person1, age: 31 };
console.log(updatedPerson); // 輸出: { name: '張三', age: 31 }

6.3 Object.assign() 方法

Object.assign() 方法用于將所有可枚舉屬性從一個或多個源對象復制到目標對象。

const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3, a: 4 };const result = Object.assign(target, source1, source2);console.log(target); // 輸出: { a: 4, b: 2, c: 3 }
console.log(result); // 輸出: { a: 4, b: 2, c: 3 } (返回修改后的目標對象)

注意:Object.assign() 執行的是淺拷貝,對于嵌套對象,只會復制引用。

6.4 深度拷貝對象

對于包含嵌套對象的復雜對象,需要進行深度拷貝。

// 使用 JSON 序列化和反序列化(有局限性,不支持函數、Symbol、循環引用等)
const original = {name: "張三",address: {city: "北京"}
};const deepCopy = JSON.parse(JSON.stringify(original));// 修改拷貝后的對象不會影響原對象
deepCopy.address.city = "上海";
console.log(original.address.city); // 輸出: 北京
console.log(deepCopy.address.city); // 輸出: 上海// 自定義深度拷貝函數(處理更復雜的情況)
function deepClone(obj) {// 處理 null 或非對象類型if (obj === null || typeof obj !== 'object') {return obj;}// 處理日期對象if (obj instanceof Date) {return new Date(obj.getTime());}// 處理數組if (Array.isArray(obj)) {return obj.map(item => deepClone(item));}// 處理普通對象const clonedObj = {};for (let key in obj) {if (obj.hasOwnProperty(key)) {clonedObj[key] = deepClone(obj[key]);}}return clonedObj;
}

6.5 對象的屬性描述符

JavaScript 允許通過屬性描述符來精確控制對象屬性的行為。

const person = {};// 使用 Object.defineProperty() 定義屬性
Object.defineProperty(person, 'name', {value: '張三',writable: false, // 是否可寫enumerable: true, // 是否可枚舉configurable: false // 是否可配置(刪除或修改描述符)
});console.log(person.name); // 輸出: 張三
person.name = '李四'; // 在非嚴格模式下靜默失敗
console.log(person.name); // 輸出: 張三(值未改變)// 定義多個屬性
Object.defineProperties(person, {age: {value: 30,writable: true,enumerable: true},email: {value: 'zhangsan@example.com',enumerable: false}
});console.log(Object.keys(person)); // 輸出: [ 'name', 'age' ] (email 不可枚舉)// 獲取屬性描述符
const nameDescriptor = Object.getOwnPropertyDescriptor(person, 'name');
console.log(nameDescriptor);
// 輸出: { value: '張三', writable: false, enumerable: true, configurable: false }// 獲取所有屬性描述符
const allDescriptors = Object.getOwnPropertyDescriptors(person);

6.6 getter 和 setter

通過 getter 和 setter 可以定義對象的訪問器屬性,實現屬性的讀取和賦值控制。

const person = {firstName: "張",lastName: "三",// getter 方法get fullName() {return `${this.firstName}${this.lastName}`;},// setter 方法set fullName(name) {const parts = name.split(" ");this.firstName = parts[0];this.lastName = parts[1] || "";}
};console.log(person.fullName); // 輸出: 張三// 使用 setter 設置值
person.fullName = "李 四";
console.log(person.firstName); // 輸出: 李
console.log(person.lastName); // 輸出: 四
console.log(person.fullName); // 輸出: 李四

7. JavaScript 中的繼承

JavaScript 使用原型鏈實現繼承。每個對象都有一個原型對象,對象從原型繼承方法和屬性。

7.1 原型鏈繼承

// 父類構造函數
function Person(name) {this.name = name;
}// 在原型上定義方法
Person.prototype.sayHello = function() {console.log(`Hello, I'm ${this.name}`);
};// 子類構造函數
function Student(name, studentId) {// 調用父類構造函數Person.call(this, name);this.studentId = studentId;
}// 設置子類的原型為父類的實例
Student.prototype = Object.create(Person.prototype);// 修復 constructor 指向
Student.prototype.constructor = Student;// 在子類原型上添加方法
Student.prototype.study = function() {console.log(`${this.name} with ID ${this.studentId} is studying.`);
};// 創建實例
const student = new Student("張三", "1001");
student.sayHello(); // 輸出: Hello, I'm 張三 (繼承自父類)
student.study(); // 輸出: 張三 with ID 1001 is studying. (子類自己的方法)// 檢查原型鏈
console.log(student instanceof Student); // 輸出: true
console.log(student instanceof Person); // 輸出: true
console.log(student instanceof Object); // 輸出: true

7.2 ES6 類的繼承

ES6 引入的類語法使繼承更加直觀。

// 父類
class Person {constructor(name) {this.name = name;}sayHello() {console.log(`Hello, I'm ${this.name}`);}
}// 子類繼承父類
class Student extends Person {constructor(name, studentId) {// 調用父類構造函數super(name);this.studentId = studentId;}study() {console.log(`${this.name} with ID ${this.studentId} is studying.`);}
}// 創建實例
const student = new Student("張三", "1001");
student.sayHello(); // 輸出: Hello, I'm 張三
student.study(); // 輸出: 張三 with ID 1001 is studying.

8. 常用的內置對象

JavaScript 提供了許多內置對象,可以直接使用它們的屬性和方法。

8.1 Object 對象

Object 是 JavaScript 中所有對象的基類,提供了許多用于操作對象的靜態方法。

// 常用的 Object 方法
Object.create(proto[, propertiesObject]) // 創建新對象
Object.defineProperty(obj, prop, descriptor) // 定義對象的屬性
Object.defineProperties(obj, props) // 定義對象的多個屬性
Object.getOwnPropertyDescriptor(obj, prop) // 獲取屬性描述符
Object.getOwnPropertyNames(obj) // 獲取所有屬性名(包括不可枚舉的)
Object.keys(obj) // 獲取所有可枚舉屬性名
Object.values(obj) // 獲取所有可枚舉屬性值
Object.entries(obj) // 獲取所有可枚舉鍵值對
Object.assign(target, ...sources) // 合并對象
Object.freeze(obj) // 凍結對象,使其不可修改
Object.seal(obj) // 密封對象,不能添加或刪除屬性
Object.isFrozen(obj) // 檢查對象是否被凍結
Object.isSealed(obj) // 檢查對象是否被密封
Object.hasOwnProperty(prop) // 檢查對象是否有指定的自有屬性

8.2 Array 對象

Array 是用于處理數組的內置對象。

// 創建數組
const arr1 = new Array(1, 2, 3);
const arr2 = [1, 2, 3];// 數組的常用方法
arr.length // 獲取或設置數組長度
arr.push(item1, ..., itemN) // 向數組末尾添加元素
arr.pop() // 刪除并返回數組最后一個元素
arr.shift() // 刪除并返回數組第一個元素
arr.unshift(item1, ..., itemN) // 向數組開頭添加元素
arr.slice(start, end) // 返回數組的一部分
arr.splice(start, deleteCount, item1, ..., itemN) // 添加/刪除元素
arr.indexOf(searchElement, fromIndex) // 查找元素位置
arr.includes(searchElement, fromIndex) // 檢查數組是否包含元素
arr.forEach(callback, thisArg) // 對數組的每個元素執行函數
arr.map(callback, thisArg) // 創建一個新數組,包含對每個元素調用函數的結果
arr.filter(callback, thisArg) // 創建一個新數組,包含通過測試的元素
arr.reduce(callback, initialValue) // 對數組元素執行歸約操作
arr.sort(compareFunction) // 對數組元素進行排序
arr.reverse() // 反轉數組元素

8.3 String 對象

String 對象用于處理文本(字符串)。

// 創建字符串
const str1 = new String("Hello");
const str2 = "Hello";// 字符串的常用方法
str.length // 獲取字符串長度
str.charAt(index) // 返回指定索引位置的字符
str.charCodeAt(index) // 返回指定索引位置字符的 Unicode 值
str.concat(str1, str2, ...) // 連接字符串
str.includes(searchString, position) // 檢查字符串是否包含子字符串
str.indexOf(searchValue, fromIndex) // 查找子字符串首次出現的位置
str.lastIndexOf(searchValue, fromIndex) // 查找子字符串最后出現的位置
str.slice(beginIndex, endIndex) // 提取字符串的一部分
str.substring(indexStart, indexEnd) // 提取字符串的子串
str.substr(start, length) // 提取字符串的子串(不推薦使用)
str.split(separator, limit) // 將字符串分割為字符串數組
str.toLowerCase() // 將字符串轉換為小寫
str.toUpperCase() // 將字符串轉換為大寫
str.trim() // 去除字符串兩端的空白字符
str.replace(searchValue, replaceValue) // 替換字符串中的子串
str.match(regexp) // 查找匹配的字符串

8.4 Number 對象

Number 對象用于處理數值。

// 創建數字
const num1 = new Number(123);
const num2 = 123;// Number 的常用方法和屬性
Number.MAX_VALUE // 表示最大的正數
Number.MIN_VALUE // 表示最小的正數
Number.MAX_SAFE_INTEGER // 表示最大的安全整數
Number.MIN_SAFE_INTEGER // 表示最小的安全整數
Number.isNaN(value) // 檢查值是否為 NaN
Number.isFinite(value) // 檢查值是否為有限數
Number.isInteger(value) // 檢查值是否為整數
Number.parseInt(string, radix) // 將字符串轉換為整數
Number.parseFloat(string) // 將字符串轉換為浮點數
num.toFixed(digits) // 格式化為指定小數位數的字符串
num.toPrecision(precision) // 格式化為指定精度的字符串
num.toString(radix) // 將數字轉換為字符串

8.5 Date 對象

Date 對象用于處理日期和時間。

// 創建日期對象
const now = new Date();
const specificDate = new Date(2023, 0, 1); // 2023年1月1日(注意月份從0開始)
const dateString = new Date("2023-01-01");// Date 的常用方法
date.getFullYear() // 獲取年份
date.getMonth() // 獲取月份(0-11)
date.getDate() // 獲取日期(1-31)
date.getDay() // 獲取星期幾(0-6,0表示星期日)
date.getHours() // 獲取小時(0-23)
date.getMinutes() // 獲取分鐘(0-59)
date.getSeconds() // 獲取秒(0-59)
date.getMilliseconds() // 獲取毫秒(0-999)
date.getTime() // 獲取時間戳(從1970-01-01開始的毫秒數)// 設置日期和時間
date.setFullYear(year)
date.setMonth(month)
date.setDate(date)
date.setHours(hours)
date.setMinutes(minutes)
date.setSeconds(seconds)// 日期格式化
date.toDateString() // 返回日期部分的字符串
date.toTimeString() // 返回時間部分的字符串
date.toISOString() // 返回 ISO 格式的字符串

8.6 Math 對象

Math 對象提供了數學常量和函數。

// Math 的常用屬性和方法
Math.PI // 圓周率 π
Math.E // 自然對數的底 e
Math.abs(x) // 絕對值
Math.ceil(x) // 向上取整
Math.floor(x) // 向下取整
Math.round(x) // 四舍五入
Math.max(x1, x2, ...) // 返回最大值
Math.min(x1, x2, ...) // 返回最小值
Math.pow(x, y) // x 的 y 次方
Math.sqrt(x) // 平方根
Math.random() // 返回 0 到 1 之間的隨機數
Math.sin(x) // 正弦函數
Math.cos(x) // 余弦函數
Math.tan(x) // 正切函數
Math.log(x) // 自然對數
Math.exp(x) // e 的 x 次方

8.7 Map 和 Set

ES6 引入的 MapSet 是用于存儲鍵值對和唯一值的集合。

// Map 對象
const map = new Map();// 添加元素
map.set("name", "張三");
map.set("age", 30);// 獲取元素
console.log(map.get("name")); // 輸出: 張三// 檢查元素是否存在
console.log(map.has("email")); // 輸出: false// 獲取 Map 的大小
console.log(map.size); // 輸出: 2// 刪除元素
map.delete("age");// 遍歷 Map
map.forEach((value, key) => {console.log(`${key}: ${value}`);
});for (let [key, value] of map) {console.log(`${key}: ${value}`);
}// Set 對象
const set = new Set([1, 2, 3, 3, 4]);// Set 自動去重
console.log(set.size); // 輸出: 4 (重復的 3 只保留一個)// 添加元素
set.add(5);// 檢查元素是否存在
console.log(set.has(3)); // 輸出: true// 刪除元素
set.delete(2);// 遍歷 Set
set.forEach(value => {console.log(value);
});for (let value of set) {console.log(value);
}

8.8 JSON 對象

JSON 對象提供了用于解析和生成 JSON 數據的方法。

// JSON 字符串
const jsonString = '{"name":"張三","age":30,"hobbies":["閱讀","編程"]}';// 解析 JSON 字符串
const obj = JSON.parse(jsonString);
console.log(obj.name); // 輸出: 張三// 將對象轉換為 JSON 字符串
const person = {name: "張三",age: 30,hobbies: ["閱讀", "編程"]
};const json = JSON.stringify(person);
console.log(json);
// 輸出: {"name":"張三","age":30,"hobbies":["閱讀","編程"]}// 帶縮進的 JSON 字符串
const prettyJson = JSON.stringify(person, null, 2);
console.log(prettyJson);
// 輸出格式化的 JSON:
// {
//   "name": "張三",
//   "age": 30,
//   "hobbies": [
//     "閱讀",
//     "編程"
//   ]
// }

9. 對象操作的最佳實踐

9.1 使用對象字面量創建對象

對象字面量是創建對象最簡潔、最易讀的方式。

// 推薦
const person = {name: "張三",age: 30
};// 不推薦(除非有特殊原因)
const person = new Object();
person.name = "張三";
person.age = 30;

9.2 使用 ES6 的類語法

對于需要創建多個相似對象的情況,使用 ES6 的類語法比傳統的構造函數模式更清晰。

// 推薦
class Person {constructor(name, age) {this.name = name;this.age = age;}sayHello() {console.log(`Hello, I'm ${this.name}`);}
}// 不推薦(除非需要兼容舊瀏覽器)
function Person(name, age) {this.name = name;this.age = age;
}Person.prototype.sayHello = function() {console.log(`Hello, I'm ${this.name}`);
};

9.3 避免修改內置對象的原型

修改內置對象(如 ObjectArray 等)的原型可能會導致不可預期的問題,應盡量避免。

// 不推薦
Array.prototype.sum = function() {return this.reduce((acc, curr) => acc + curr, 0);
};

9.4 使用對象展開運算符或 Object.assign() 合并對象

const defaults = {timeout: 3000,retries: 3
};const options = {timeout: 5000,url: "https://api.example.com"
};// 推薦
const config = { ...defaults, ...options };// 或者
const config = Object.assign({}, defaults, options);

9.5 優先使用 const 聲明對象

除非需要重新賦值整個對象,否則應使用 const 聲明對象,這有助于防止意外的對象替換。

// 推薦
const person = {name: "張三",age: 30
};// 仍然可以修改對象的屬性
person.age = 31;// 不推薦(除非需要重新賦值整個對象)
let person = {name: "張三",age: 30
};

9.6 使用解構賦值訪問對象屬性

解構賦值可以使代碼更簡潔、更易讀。

const user = {name: "張三",email: "zhangsan@example.com",role: "admin"
};// 推薦
const { name, email, role } = user;
console.log(name, email, role);// 不推薦
const name = user.name;
const email = user.email;
const role = user.role;
console.log(name, email, role);

9.7 注意 this 的綁定問題

在 JavaScript 中,this 的值取決于函數的調用方式,而不是定義方式。在處理事件處理程序、回調函數等情況時,需要特別注意 this 的綁定。

const person = {name: "張三",greet: function() {console.log(`Hello, I'm ${this.name}`);},delayedGreet: function() {// 在 setTimeout 中,this 不會指向 person 對象setTimeout(function() {console.log(`Hello, I'm ${this.name}`); // this 可能是全局對象或 undefined}, 1000);},delayedGreetFixed: function() {// 方法1: 使用 bindsetTimeout(function() {console.log(`Hello, I'm ${this.name}`);}.bind(this), 1000);// 方法2: 使用箭頭函數(繼承外層作用域的 this)setTimeout(() => {console.log(`Hello, I'm ${this.name}`);}, 2000);}
};

9.8 安全地訪問嵌套對象屬性

當訪問嵌套對象的屬性時,應防止因中間屬性不存在而導致的錯誤。

const user = {profile: {name: "張三",address: {city: "北京"}}
};// 不安全(如果 user.profile 或 user.profile.address 不存在,會拋出錯誤)
console.log(user.profile.address.city);// 安全的方式1: 逐步檢查
let city = "未知";
if (user && user.profile && user.profile.address) {city = user.profile.address.city;
}
console.log(city);// 安全的方式2: 使用可選鏈操作符(ES11 特性)
console.log(user?.profile?.address?.city || "未知");// 安全的方式3: 使用 try-catch
try {console.log(user.profile.address.city);
} catch (error) {console.log("未知");
}

10. 總結

JavaScript 對象是該語言的核心概念之一,理解和掌握對象的操作對于編寫高效、可維護的 JavaScript 代碼至關重要。本指南涵蓋了 JavaScript 對象的基本概念、創建方法、屬性和方法操作、遍歷方式、高級特性、繼承機制以及常見的內置對象等內容。

通過靈活運用這些知識,您可以更好地組織和管理數據,實現復雜的功能,并編寫更加優雅和高效的 JavaScript 代碼。隨著 JavaScript 語言的不斷發展,對象相關的特性也在持續改進,建議保持學習最新的語言特性和最佳實踐。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/96174.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/96174.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/96174.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【競賽系列】機器學習實操項目04——客戶信用評估模型開發全流程(baseline)

上一章:機器學習實操項目03——Scikit-learn介紹及簡單分類案例 下一章: 機器學習核心知識點目錄:機器學習核心知識點目錄 機器學習實戰項目目錄:【從 0 到 1 落地】機器學習實操項目目錄:覆蓋入門到進階,大…

C++中的單例模式的實現

1 什么是單例模式單例模式 是一種創建型設計模式,確保一個類在整個程序生命周期中只有一個實例,并提供一個全局訪問點。核心要求:類不能被外部隨意創建(禁止 public 構造函數或限制實例數量)。不能被復制或移動。提供一…

匯編基礎1

1.格式偽操作:它們不是ARM處理器實際的指令(如MOV, ADD等),而是寫給匯編器看的命令,用于指導匯編器如何工作area reset, code, readonlycode32entry內容 endarea: 這是最重要的一個偽操作,用…

設計模式(C++)詳解—單例模式(2)

<摘要> 單例模式是創建型設計模式中最簡單但應用最廣泛的模式之一&#xff0c;它確保一個類只有一個實例并提供全局訪問點。本文從歷史背景和核心概念出發&#xff0c;系統闡述了單例模式的產生緣由和演進脈絡&#xff0c;深入剖析了其在資源管理、狀態一致性和訪問控制方…

kafka如何保證消息的順序性

kafka如何保證消息的順序性 Kafka只能在分區&#xff08;Partition&#xff09;級別保證消息的順序性&#xff0c;而不能在主題&#xff08;Topic&#xff09;級別保證全局順序。 核心原理&#xff1a;分區和偏移量分區&#xff08;Partition&#xff09;是順序性的基礎&#x…

傳輸層:UDP/TCP協議

網絡協議圖 一.UDP 特點: 無連接&#xff0c;不可靠&#xff0c;面向數據報&#xff0c;全雙工&#xff08;前面網絡編程中介紹過&#xff09; 格式: 服務器的端口號一般都是程序員指定的(這樣你才能訪問到),客戶端的端口號是系統自動分配的(如果提前指定好, 可能會與其他程…

A/B測試全解析:原理、流程與實戰案例

A/B測試&#xff08;AB Testing&#xff09;原理與實踐全解析 在數據驅動的時代&#xff0c;A/B測試幾乎是每一個互聯網公司都會使用的實驗方法。無論是電商平臺優化轉化率&#xff0c;還是內容平臺提升點擊率&#xff0c;抑或是游戲公司提升留存&#xff0c;A/B測試都是最常見…

循環神經網絡(三):小練習

RNN小練習 要求&#xff1a; 假設有 4 個字 吃 了 沒 &#xff1f;&#xff0c;請使用 torch.nn.RNN 完成以下任務 將每個進行 one-hot 編碼請使用 吃 了 沒 作為輸入序列&#xff0c;了 沒 &#xff1f; 作為輸出序列RNN 的 hidden_size 64請將 RNN 的輸出使用全連接轉換成 4…

ESPIDF官方文檔,啟用dhcp會禁用對應的STA或AP的靜態IP,我測試STA確實是,但是AP不是,為什么

1. STA 模式下的 DHCP&#xff08;客戶端角色&#xff09;ESP32 當 Station&#xff08;STA&#xff09; 時&#xff0c;它的行為就跟你的手機/筆記本連 Wi-Fi 一樣&#xff1a;DHCP 客戶端 → 去路由器&#xff08;DHCP 服務器&#xff09;要一個 IP。特點啟用 DHCP&#xff0…

cocos2d. 3.17.2 c++如何實現下載斷點續傳zip壓縮包帶進度條

新建類CurlDown #include “curl/curl.h” #include using namespace std; USING_NS_CC; /** 資源下載curl */ class CurlDown { public: CurlDown(); ~CurlDown(); void StartDownResZip(string downLoadUrl, int64_t totalSize); //下載控制 void downloadControler(); //下…

MySQL 整型數據類型:選對數字類型,讓存儲效率翻倍

MySQL 整型數據類型&#xff1a;選對數字類型&#xff0c;讓存儲效率翻倍 在 MySQL 中&#xff0c;整型&#xff08;整數類型&#xff09;是最常用的數據類型之一&#xff0c;從用戶 ID 到商品數量&#xff0c;幾乎所有涉及數字的場景都離不開它。但你知道嗎&#xff1f;選對整…

公司電腦監控軟件有哪些?公司電腦監控軟件應該怎么選擇

大家好呀&#xff0c;電競直播運營團隊常常面臨 “直播腳本被抄襲、用戶付費數據篡改、主播話術外泄” 的問題&#xff01;尤其是獨家直播流程腳本、用戶充值記錄、主播互動話術庫、賽事解說手稿&#xff0c;一旦泄露可能導致競品跟風、用戶信任下降、直播競爭力減弱&#xff5…

ARM裸機開發:鏈接腳本、進階Makefile(bsp)、編譯過程、beep實驗

一、鏈接腳本的作用&#xff1f;各個段存放什么數據類型&#xff08;一&#xff09;鏈接腳本內容SECTIONS {. 0x87800000;.text : {obj/start.o*(.text)}.rodata ALIGN(4) : {*(.rodata*)}.data ALIGN(4) : {*(.data)}__bss_start .;.bss ALIGN(4) : {*(.bss) *(COMMON)}__bs…

Linux驅動開發(1)概念、環境與代碼框架

一、驅動概念驅動與底層硬件直接打交道&#xff0c;充當了硬件與應用軟件中間的橋梁。1、具體任務&#xff08;1&#xff09;讀寫設備寄存器&#xff08;實現控制的方式&#xff09;&#xff08;2&#xff09;完成設備的輪詢、中斷處理、DMA通信&#xff08;CPU與外設通信的方式…

計算機視覺(十):ROI

什么是感興趣區域&#xff08;ROI&#xff09;&#xff1f; 在計算機視覺中&#xff0c;**感興趣區域&#xff08;ROI&#xff09;**指的是圖像中包含我們想要分析、處理或識別的目標或特征的特定子集。就像我們在閱讀一本書時會聚焦于某個重要的段落&#xff0c;計算機視覺系統…

Jenkins 構建 Node 項目報錯解析與解決——pnpm lockfile 問題實戰

在使用 Jenkins 自動化構建 Node.js 項目時&#xff0c;經常會遇到類似報錯&#xff1a; ERR_PNPM_OUTDATED_LOCKFILE? Cannot install with "frozen-lockfile" because pnpm-lock.yaml is not up to date with package.json Error: Cannot find module node_module…

Kafka在多環境中安全管理敏感

1. 配置提供者是什么&#xff1f; 配置提供者&#xff08;ConfigProvider&#xff09;是一類按需“拉取配置”的組件&#xff1a;應用讀取配置時&#xff0c;按約定的占位符語法去外部來源&#xff08;目錄、環境變量、單一 properties 文件、你自定義的來源……&#xff09;取…

編程工具的演進邏輯:從Python IDLE到Arduino IDE的深度剖析

引言:工具進化的本質 在編程學習與開發的道路上,我們總會與各種各樣的工具相遇。一個有趣的現象是,無論是初學者的第一款工具Python IDLE,還是硬件愛好者常用的Thonny和Arduino IDE,它們都自稱“集成開發環境”(IDE)。這背后隱藏著怎樣的邏輯? 本文將帶你深入分析這三…

p10k configure執行報錯: ~/powerlevel10k/config/p10k-lean.zsh is not readable

[ERROR] p10k configure: ~/powerlevel10k/config/p10k-lean.zsh is not readable 背景 我移動了Powerlevel10k文件夾的位置&#xff0c;導致p10k configure命令找不到powerlevel10k文件夾的位置。 原來Powerlevel10k的位置&#xff1a;~/powerlevel10k 移動后Powerlevel10k的位…

Java 學習筆記(進階篇3)

1. 美化界面關鍵邏輯 1&#xff1a;// 相對路徑&#xff1a;直接從項目的 src 目錄開始寫&#xff0c;不包含 D:\ 和個人名字 ImageIcon bg new ImageIcon("src/image/background.png"); JLabel background new JLabel(bg);這兩行代碼是 Swing 中加載并顯示圖片的經…