掌握 JavaScript 物件:即時使用者管理系統中的方法、屬性、原型和 __proto__
これは、JavaScript でのさまざまなオブジェクト メソッドの実際の使用法を示すリアルタイム プロジェクト シナリオです。このシナリオでは、ユーザーが自分のプロファイルを管理できるようにするオンライン アプリケーション用のユーザー管理システムを構築します。提供されている各メソッドを使用する方法とその理由を説明します。
リアルタイム プロジェクト シナリオ: ユーザー管理システム
プロジェクト概要:
このプロジェクトでは、ユーザーは自分のプロフィールを登録および更新できます。ユーザー データはオブジェクトに保存されており、ロールごとのユーザーのグループ化、特定のプロパティの凍結、特定の検証チェックの確保、ユーザー入力変換の処理などのさまざまな機能が必要です。
1. Object.assign(): ユーザーデータのマージ
シナリオ: ユーザーがプロフィールを更新するとき、更新されたデータを既存のユーザー オブジェクトにマージする必要があります。
使用理由: Object.assign() を使用すると、さまざまなオブジェクトのプロパティを組み合わせることができます。既存のユーザー オブジェクトを更新された値と簡単にマージできます。
例:
const existingUser = { name: "John", age: 30, role: "admin" }; const updatedData = { age: 31, city: "New York" }; // Merging updated data into the existing user object const mergedUser = Object.assign({}, existingUser, updatedData); console.log(mergedUser); // Output: { name: "John", age: 31, role: "admin", city: "New York" }
2. Object.create(): ユーザー ロールのプロトタイピング
シナリオ: 管理者やゲストなど、ユーザーのロールに関連する特定のメソッドを継承するユーザー オブジェクトを作成する必要があるとします。
使用理由: Object.create() を使用すると、プロトタイプから継承するオブジェクトを作成できるため、同様のオブジェクト間で機能を再利用できます。
例:
const rolePrototype = { getRole: function() { return this.role; } }; // Creating a user object with role prototype const adminUser = Object.create(rolePrototype); adminUser.role = "admin"; console.log(adminUser.getRole()); // Output: "admin"
3. Object.defineProperty(): 読み取り専用プロパティの設定
シナリオ: ユーザー プロファイルでは、ユーザー ID は作成後に不変である必要があります。ユーザー ID が変更できないことを確認する必要があります。
使用理由: Object.defineProperty() を使用すると、プロパティの書き込みや変更が可能かどうかなど、プロパティの特性を制御できます。
例:
const user = { name: "Alice" }; Object.defineProperty(user, 'userID', { value: '12345', writable: false, // Making userID read-only enumerable: true }); console.log(user.userID); // Output: 12345 user.userID = '67890'; // This will not change userID console.log(user.userID); // Output: 12345
もちろんです!以下に、Object.defineProperty メソッドを使用した enumerable: true と enumerable: false の違いを示す例を示します。
enumerable の例: true
この例では、enumerable を true に設定してプロパティを定義します。このプロパティは列挙操作で表示されます。
const user1 = { name: "Alice" }; // Define an enumerable property Object.defineProperty(user1, 'userID', { value: '12345', writable: false, // Making userID read-only enumerable: true // This property is enumerable }); // Check enumerable properties console.log("For...in loop:"); for (let key in user1) { console.log(key); // Logs: name, userID } console.log("Object.keys():", Object.keys(user1)); // Logs: ['name', 'userID'] console.log("JSON.stringify():", JSON.stringify(user1)); // Logs: {"name":"Alice","userID":"12345"}
列挙可能な例: false
この例では、enumerable を false に設定してプロパティを定義します。このプロパティは列挙操作では表示されません。
const user2 = { name: "Bob" }; // Define a non-enumerable property Object.defineProperty(user2, 'userID', { value: '67890', writable: false, // Making userID read-only enumerable: false // This property is not enumerable }); // Check enumerable properties console.log("For...in loop:"); for (let key in user2) { console.log(key); // Logs: name (userID is not logged) } console.log("Object.keys():", Object.keys(user2)); // Logs: ['name'] (userID is not included) console.log("JSON.stringify():", JSON.stringify(user2)); // Logs: {"name":"Bob"} (userID is not included)
出力の概要
-
user1 の場合 (列挙可能: true):
- 名前とユーザー ID の両方を for...in ループに記録します。
- Object.keys() は ['name', 'userID'] を返します。
- JSON.stringify() には両方のプロパティが含まれます。
-
user2 の場合 (列挙可能: false):
- for...in ループには名前のみが記録されます。
- Object.keys() は ['name'] を返します。
- JSON.stringify() には name プロパティのみが含まれます。
4. Object.defineProperties(): 複数のプロパティの設定
シナリオ: 新しいユーザーを登録するとき、ユーザー ID とロールの両方を定義する必要があります。ここで、ユーザー ID は不変ですが、ロールは書き込み可能です。
使用理由: Object.defineProperties() は、異なる特性を持つ複数のプロパティを一度に定義する場合に便利です。
例:
const newUser = {}; Object.defineProperties(newUser, { userID: { value: '98765', writable: false, enumerable: true }, role: { value: 'guest', writable: true, enumerable: true } }); console.log(newUser); // Output: { userID: "98765", role: "guest" }
5. Object.entries(): ユーザーデータの反復処理
シナリオ: 管理パネルで見やすくするために、ユーザーのプロファイルのすべてのキーと値のペアを表示する必要があります。
使用理由: Object.entries() は、オブジェクトをキーと値のペアの配列に変換します。これにより、データの反復処理が容易になります。
例:
const userProfile = { name: "Alice", age: 28, city: "Paris" }; const entries = Object.entries(userProfile); entries.forEach(([key, value]) => { console.log(`${key}: ${value}`); }); // Output: // name: Alice // age: 28 // city: Paris
6. Object.freeze(): ユーザー プロファイルの凍結
シナリオ: ユーザーがプロファイルを送信した後、偶発的な変更を防ぐためにプロファイル全体を不変にしたいとします。
使用理由: Object.freeze() は、オブジェクトのプロパティの追加、削除、変更を防ぎます。
例:
const userProfile = { name: "John", age: 31, city: "New York" }; Object.freeze(userProfile); userProfile.city = "San Francisco"; // This change won't be applied console.log(userProfile.city); // Output: "New York"
7. Object.fromEntries(): フォーム データをオブジェクトに変換する
シナリオ: フォーム送信からユーザー プロファイル データを受信した後、それをキーと値のペアの配列として取得し、オブジェクトに変換し直す必要があります。
Why Use It: Object.fromEntries() converts an array of key-value pairs into an object.
Example:
const formData = [['name', 'Alice'], ['age', '28'], ['city', 'Paris']]; const userProfile = Object.fromEntries(formData); console.log(userProfile); // Output: { name: "Alice", age: "28", city: "Paris" }
8. groupBy() (Custom Implementation): Group Users by Role
Scenario: We need to categorize users into different groups based on their roles (e.g., admin, guest).
Why Use It: JavaScript doesn’t have a built-in groupBy() function, but we can create one to group users by a certain property like their role.
Example:
const users = [ { name: "Alice", role: "admin" }, { name: "Bob", role: "guest" }, { name: "Charlie", role: "admin" }, ]; const groupBy = (array, key) => { return array.reduce((acc, obj) => { const keyValue = obj[key]; if (!acc[keyValue]) acc[keyValue] = []; acc[keyValue].push(obj); return acc; }, {}); }; const groupedUsers = groupBy(users, 'role'); console.log(groupedUsers); // Output: // { // admin: [{ name: "Alice", role: "admin" }, { name: "Charlie", role: "admin" }], // guest: [{ name: "Bob", role: "guest" }] // }
9. Object.hasOwn(): Checking User-Specific Properties
Scenario: Before allowing a user to access a feature, we want to check if they have a specific property like role.
Why Use It: Object.hasOwn() ensures that the property exists directly on the object and not in the prototype chain.
Example:
const user = { name: "Alice", role: "admin" }; console.log(Object.hasOwn(user, 'role')); // true console.log(Object.hasOwn(user, 'age')); // false
10. Object.is(): Strict Equality for Profile Comparison
Scenario: We want to strictly compare two profile objects to check if they are exactly the same, including NaN.
Why Use It: Object.is() compares two values and correctly handles special cases, such as comparing NaN.
Example:
const user1 = { name: "John" }; const user2 = { name: "John" }; console.log(Object.is(user1, user2)); // false (different references) console.log(Object.is(NaN, NaN)); // true
11. Object.keys() and Object.values(): Displaying User Data
Scenario: We want to get an array of keys (property names) or values (property values) from a user's profile.
Why Use It: Object.keys() is used to retrieve the keys, and Object.values() retrieves the values of an object.
Example:
const user = { name: "John", age: 30, city: "New York" }; console.log(Object.keys(user)); // ["name", "age", "city"] console.log(Object.values(user)); // ["John", 30, "New York"]
12. Object.hasOwnProperty(): Custom Property Check
Scenario: When working with inherited objects, we need to ensure a property exists directly on an object and not on its prototype.
Why Use It: Object.hasOwnProperty() is useful for checking if a property belongs to the object itself, not its prototype chain.
Example:
const user = { name: "Alice" }; console.log(user.hasOwnProperty('name')); // true console.log(user.hasOwnProperty('toString')); // false (inherited from prototype)
Here’s a detailed comparison of similar or related Object methods and additional topics, explaining how they differ in usage and when to use each one. This will help you choose the right method for specific use cases in your project.
1. Object.assign() vs Object.create()
Similarity:
Both Object.assign() and Object.create() are used to create objects.
Differences:
Method | Purpose | When to Use |
---|---|---|
Object.assign() | Copies the properties of one or more objects into another object. | When you need to merge or shallow copy objects (e.g., updating user data or combining settings). |
Object.create() | Creates a new object with a specified prototype. | When you need to set up prototypal inheritance, such as creating users with role-specific behaviors. |
Example:
// Object.assign: Merging objects const target = {}; const source = { name: "John" }; Object.assign(target, source); // { name: "John" } // Object.create: Inheriting from a prototype const rolePrototype = { role: "admin" }; const adminUser = Object.create(rolePrototype); console.log(adminUser.role); // "admin"
2. Object.defineProperty() vs Object.defineProperties()
Similarity:
Both methods define properties with configurable characteristics (e.g., writable, enumerable).
Differences:
Method | Purpose | When to Use |
---|---|---|
Object.defineProperty() | Defines or modifies a single property on an object. | Use when you need fine-grained control over a single property (e.g., making userID read-only). |
Object.defineProperties() | Defines or modifies multiple properties at once. | Use when you need to set up multiple properties with different configurations in one go. |
Example:
// Object.defineProperty: Setting a single property const user = {}; Object.defineProperty(user, 'userID', { value: '123', writable: false }); // Object.defineProperties: Setting multiple properties Object.defineProperties(user, { role: { value: 'admin', writable: true }, age: { value: 30, enumerable: true } });
3. Object.entries() vs Object.keys() vs Object.values()
Similarity:
All three methods return information about the properties of an object, but in different forms.
Differences:
Method | Purpose | When to Use |
---|---|---|
Object.entries() | Returns an array of key-value pairs. | Use when you need both keys and values (e.g., iterating over a profile’s data for display). |
Object.keys() | Returns an array of keys (property names). | Use when you need only the property names (e.g., validating fields in a user form). |
Object.values() | Returns an array of values. | Use when you only need the property values (e.g., aggregating numerical values like expenses in a budget app). |
Example:
const userProfile = { name: "John", age: 30, city: "New York" }; // Object.entries: Key-value pairs console.log(Object.entries(userProfile)); // [["name", "John"], ["age", 30], ["city", "New York"]] // Object.keys: Only keys console.log(Object.keys(userProfile)); // ["name", "age", "city"] // Object.values: Only values console.log(Object.values(userProfile)); // ["John", 30, "New York"]
4. Object.freeze() vs Object.seal()
Similarity:
Both methods control modifications to an object but differ in the level of restriction they impose.
Differences:
Method | Purpose | When to Use |
---|---|---|
Object.freeze() | Makes an object completely immutable (cannot add, remove, or change properties). | Use when you need a strict immutability guarantee, such as locking down a user’s profile after registration. |
Object.seal() | Prevents adding or removing properties but allows modification of existing ones. | Use when you need to prevent property addition/removal but still allow changes to existing properties. |
Example:
const user = { name: "Alice", role: "guest" }; // Object.freeze: Completely immutable Object.freeze(user); user.name = "Bob"; // Won't change delete user.role; // Won't delete // Object.seal: Modify existing, but can't add/remove Object.seal(user); user.name = "Bob"; // Allowed delete user.role; // Not allowed
5. Object.hasOwnProperty() vs Object.hasOwn()
Similarity:
Both methods check if an object has a particular property, but there are slight technical differences.
Differences:
Method | Purpose | When to Use |
---|---|---|
Object.hasOwnProperty() | Checks if a property exists directly on the object (older). | Use for older JavaScript codebases where backward compatibility is needed. |
Object.hasOwn() | Similar to hasOwnProperty() but designed as a more modern and robust method (ES2022). | Use in modern JavaScript projects for checking if an object has a direct property (avoids issues with prototypes). |
Example:
const user = { name: "John" }; // Object.hasOwnProperty console.log(user.hasOwnProperty('name')); // true console.log(user.hasOwnProperty('age')); // false // Object.hasOwn console.log(Object.hasOwn(user, 'name')); // true console.log(Object.hasOwn(user, 'age')); // false
6. Object.is() vs ===
Similarity:
Both are used for comparing values, but they handle special cases differently.
Differences:
Method | Purpose | When to Use |
---|---|---|
Object.is() | Compares two values, with special handling for NaN, -0, and +0. | Use when you need strict equality, especially when comparing special values like NaN or zero. |
=== | Standard strict equality check. | Use for typical strict equality checks, but be aware that NaN === NaN is false, and -0 === +0 is true. |
Example:
console.log(NaN === NaN); // false console.log(Object.is(NaN, NaN)); // true console.log(-0 === +0); // true console.log(Object.is(-0, +0)); // false
7. Object.fromEntries() vs Object.entries()
Similarity:
Both methods convert between objects and key-value pairs, but in opposite directions.
Differences:
Method | Purpose | When to Use |
---|---|---|
Object.entries() | Converts an object into an array of key-value pairs. | Use when you need to iterate or manipulate key-value pairs from an object. |
Object.fromEntries() | Converts an array of key-value pairs into an object. | Use when you receive data as an array of pairs (e.g., form data) and need to transform it back into an object. |
Example:
const userProfile = { name: "Alice", age: 28 }; const entries = Object.entries(userProfile); // From key-value pairs to object const newProfile = Object.fromEntries(entries); console.log(newProfile); // { name: "Alice", age: 28 }
8. Object.keys() vs Object.getOwnPropertyNames()
Similarity:
Both methods retrieve the keys of an object.
Differences:
Method | Purpose | When to Use |
---|---|---|
Object.keys() | Returns only the enumerable (visible) property keys of an object. | Use when you only need the enumerable properties (common for iterating over user objects). |
Object.getOwnPropertyNames() | Returns both enumerable and non-enumerable property keys. | Use when you need all properties, including non-enumerable ones (e.g., metadata, hidden properties). |
Example:
const user = { name: "Alice" }; Object.defineProperty(user, 'role', { value: 'admin', enumerable: false }); console.log(Object.keys(user)); // ["name"] console.log(Object.getOwnPropertyNames(user)); // ["name", "role"]
In this enhanced version, we will dive deeper into creating your own methods and properties in JavaScript objects, as well as using prototypes. This will help provide even more flexibility and power in a real-time project scenario.
- Creating Custom Methods and Properties in JavaScript Objects:
JavaScript objects allow you to define your own properties and methods. This can be useful when you want to extend the capabilities of an object to perform specific tasks related to your application.
Example Scenario: Adding a Role Check in the User Management System
Imagine you're building a user management system where each user has specific roles, like "admin" or "editor." You want to create a method to check the user's role.
// Create a user object const user = { name: 'John Doe', role: 'admin', // Define a custom method to check the role checkRole() { if (this.role === 'admin') { return `${this.name} has admin access`; } else { return `${this.name} is a regular user`; } } }; console.log(user.checkRole()); // John Doe has admin access
Here, we defined a custom method checkRole within the user object to determine if the user has admin privileges. This can be expanded to check for multiple roles and permissions.
- Using Object Prototypes to Extend Functionality
JavaScript prototypes allow you to add properties or methods to all instances of a particular object type. For example, you can add methods to an object prototype, so all objects created with a specific constructor can access that method.
Example Scenario: Extending the User Object with Prototypes
Let’s say you want all users in the system to have access to a method that can toggle their roles between "admin" and "user" without redefining it for every user object.
// Define the constructor function for User function User(name, role) { this.name = name; this.role = role; } // Add a method to User prototype to toggle role User.prototype.toggleRole = function() { this.role = this.role === 'admin' ? 'user' : 'admin'; }; // Create user instances const user1 = new User('Alice', 'user'); const user2 = new User('Bob', 'admin'); console.log(user1.role); // user user1.toggleRole(); // Toggling role console.log(user1.role); // admin
In this example, toggleRole is added to the User.prototype, meaning any user instance created will inherit this method. This is useful for reusing code and maintaining DRY (Don't Repeat Yourself) principles in a real-time system.
By mastering custom methods, properties, and prototypes, you can create more advanced, maintainable, and efficient systems tailored to the needs of your application, such as the User Management System scenario described.
1. __proto__ (Dunder Proto or Double Underscore Proto)
In JavaScript, __proto__ and prototype are two related but distinct concepts that often confuse developers, especially when working with objects and inheritance. Here's a breakdown:
- __proto__ is an internal property of an object that points to its prototype.
- It refers to the actual prototype that was used to create the object instance.
- This is part of JavaScript's prototypal inheritance system. When you try to access a property or method on an object, if it's not found directly on the object, JavaScript will look up the prototype chain via __proto__.
Key Points:
- Every object has a __proto__ property (except Object.prototype, which is the root of the prototype chain).
- __proto__ is a reference to the object's prototype, which is shared among all instances of that object.
Example:
const person = { name: 'Alice', sayHello() { console.log(`Hello, my name is ${this.name}`); } }; // Creating another object that inherits from 'person' const student = { __proto__: person, grade: 'A' }; console.log(student.name); // Inherited from 'person' => 'Alice' student.sayHello(); // Inherited method => 'Hello, my name is Alice'
In this example, student doesn't directly have the name property or the sayHello method, but it can access them because its __proto__ points to person.
2. prototype
- prototype is a property of constructor functions (functions used to create objects).
- When you create an object using a constructor function (like using new), the newly created object’s __proto__ property is set to point to the constructor’s prototype object.
- Only functions have the prototype property, and it's used to set up inheritance.
Key Points:
- Functions (that act as constructors) have a prototype property.
- Instances of that function will have their __proto__ set to the prototype of the constructor.
- You can add properties and methods to the constructor’s prototype, and they will be shared across all instances.
Example:
function User(name) { this.name = name; } // Adding a method to the User prototype User.prototype.sayHello = function() { console.log(`Hello, my name is ${this.name}`); }; // Creating new user instances const user1 = new User('John'); const user2 = new User('Jane'); // Both instances inherit the sayHello method from User.prototype user1.sayHello(); // 'Hello, my name is John' user2.sayHello(); // 'Hello, my name is Jane'
In this case:
- The User function has a prototype property, and any instance created by new User() will have its __proto__ linked to User.prototype.
- The sayHello method is defined on User.prototype, so both user1 and user2 can use it without having a separate copy of it.
Key Differences between __proto__ and prototype:
Aspect | __proto__ | prototype |
---|---|---|
What it refers to | The prototype of an object instance | The prototype of a constructor function |
Where it’s used | On all objects | On functions (constructor functions) |
Functionality | Used to access the prototype chain of an object | Used to define methods/properties shared by instances |
Access | Can be accessed directly (e.g., obj.__proto__) | Used during object creation with new keyword |
Example Illustrating Both:
// Constructor function function Animal(name) { this.name = name; } // Adding a method to the prototype of the constructor Animal.prototype.makeSound = function() { console.log(`${this.name} makes a sound`); }; // Creating an instance const dog = new Animal('Rex'); // dog.__proto__ points to Animal.prototype console.log(dog.__proto__ === Animal.prototype); // true // dog can access the method from Animal.prototype dog.makeSound(); // Rex makes a sound
- Animal is the constructor function.
- Animal.prototype contains the method makeSound.
- When dog is created, dog.__proto__ is set to Animal.prototype, allowing dog to inherit the makeSound method.
Conclusion
- __proto__ is an internal property of every object that points to its prototype. It's used to look up properties in the prototype chain.
- prototype is a property of functions (especially constructor functions) that allows you to add methods and properties that will be inherited by all instances created from the constructor.
By understanding the difference between __proto__ and prototype, you can take full advantage of JavaScript's prototypal inheritance system for efficient object creation and method sharing.
以上是掌握 JavaScript 物件:即時使用者管理系統中的方法、屬性、原型和 __proto__的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

JavaScript在Web開發中的主要用途包括客戶端交互、表單驗證和異步通信。 1)通過DOM操作實現動態內容更新和用戶交互;2)在用戶提交數據前進行客戶端驗證,提高用戶體驗;3)通過AJAX技術實現與服務器的無刷新通信。
