• About
  • Advertise
  • Privacy & Policy
  • Contact
NQ NEWS
  • Kiến thức tổng hợp
    • Development
    • Deep Learning
    • Cloud Computing
    • Kiến thức bảo mật
    • Tin học văn phòng
  • Thủ thuật
    • Phần Mềm
    • Sửa lỗi máy tính
    • Bảo mật máy tính
    • Tăng tốc máy tính
    • Thủ thuật Wifi
  • Quản trị hệ thống
    • Giải pháp bảo mật
    • Mail Server
    • Mạng LAN – WAN
    • Máy chủ
    • Windows Server 2012
  • Tin tức
No Result
View All Result
  • Kiến thức tổng hợp
    • Development
    • Deep Learning
    • Cloud Computing
    • Kiến thức bảo mật
    • Tin học văn phòng
  • Thủ thuật
    • Phần Mềm
    • Sửa lỗi máy tính
    • Bảo mật máy tính
    • Tăng tốc máy tính
    • Thủ thuật Wifi
  • Quản trị hệ thống
    • Giải pháp bảo mật
    • Mail Server
    • Mạng LAN – WAN
    • Máy chủ
    • Windows Server 2012
  • Tin tức
No Result
View All Result
NQ NEWS
No Result
View All Result
Home Kiến thức tổng hợp

JavaScript khi Object được tạo từ hư vô

@admiz by @admiz
04/05/2021
in Kiến thức tổng hợp
0
Javascript Khi Object được Tạo Từ Hư Vô 60902d069ee16.jpeg

Một ngày đẹp giời tôi cần kiểm tra thuộc tính của 1 object trước khi thực hiện một vài thao tác khác. Theo thói quen từ lúc đi học, cú pháp rất thông dụng obj.hasOwnProperty(tên-thuộc-tính-cần-kiểm-tra) sẽ được dùng, trả về true nếu obj của ta đúng là có thuộc tính kia, trả về falsetrong trường hợp ngược lại. Ấy vậy mà cú pháp này bị ESlint (một công cụ linting trong JavaScript mà các công ty hay dùng) báo lỗi. Thử ví dụ sau nhé:

let obj = {

name: “Nguyen Minh Trung”,

skill: “JavaScript”

;

let hasSkill = obj.hasOwnProperty(“skill”);

Với ESlint, dòng code trên là chưa đạt “chuẩn”, một khi không sửa thì nó sẽ không cho build project. Lỗi đây:

Ảnh 2.

ESlint phân loại lỗi trên vào dạng “Disallow use of Object.prototypes builtins directly (no-prototype-builtins)”. Phải sửa như sau:

// Viết chưa chuẩn –> báo lỗi

let hasSkill = obj.hasOwnProperty(“skill”);

// Viết CHUẨN

let hasSkill = Object.prototype.hasOwnProperty.call(obj, “skill”);

Chú ý là Object khác với obj. Trong ảnh ở trên tôi viết là object, tuy vẫn đúng nhưng để cho dễ phân biệt, tôi đã sửa lại trong bài viết này thành obj (còn ảnh thì lười quá để tạm).

Tại sao ESlint lại bắt lỗi “no-prototype-builtins” trên?

Thấy việc bắt lỗi này khá là kỳ quặc, tôi tra documentation của ESlint thì thấy họ ghi như sau:

In ECMAScript 5.1, Object.create was added, which enables the creation of objects with a specified [[Prototype]]. Object.create(null) is a common pattern used to create objects that will be used as a Map. This can lead to errors when it is assumed that objects will have properties from Object.prototype. This rule prevents calling Object.prototype methods directly from an object.

Dịch nôm na có nghĩa là:

Kể từ ECMAScript 5.1, Object có thể được tạo ra bằng cú pháp Object.create(). Object mới tạo ra sẽ có property __proto__, property này sẽ là object (object bên trong object) hay là null thì tùy thuộc vào tham số truyền vào lúc gọi Object.create() của lập trình viên. Từ đây nảy sinh ra việc lập trình viên sử dụng Object.create(null) để tạo Map (cũng là 1 dạng object, nhưng đặc biệt hơn). Điều này tiềm ẩn nguy cơ gây lỗi bởi thông thường nếu không phải là tác giả của đoạn code gốc thì chúng ta sẽ mặc nhiên cho rằng: “đã là objects thì sẽ có thuộc tính (tức là properties) từ Object.prototype, rồi cứ thế tìm cách gọi trực tiếp các methods của Object.prototype”, dẫn đến báo lỗi. Quy định này (của ESlint) cho phép ngăn chắn các lỗi kiểu trên.

Đoạn trên đọc thì chưa hiểu gì! Chỉ biết đại loại là ESlint cho rằng ta không nên viết code như dưới đây:

var hasBarProperty = foo.hasOwnProperty(“bar”);

var isPrototypeOfBar = foo.isPrototypeOf(bar);

var barIsEnumerable = foo.propertyIsEnumerable(“bar”);

mà nên viết là:

var hasBarProperty = Object.prototype.hasOwnProperty.call(foo, “bar”);

var isPrototypeOfBar = Object.prototype.isPrototypeOf.call(foo, bar);

var barIsEnumerable = { .propertyIsEnumerable.call(foo, “bar”);

Ok, cứ tạm thế đã. Vậy cách tạo object thông qua Object.create() nghĩa là sao? Lại còn Object.create(null) nữa chứ!!!

Bình thường nhất, chúng ta đều được hướng dẫn 2 cách sau được dùng để tạo object:

• 1 là sử dụng toán tử new với object constructor: new Object(). Cách này cá nhân tôi ít dùng.

• 2 là sử dụng object literal (chính là 2 dấu ngoặc nhọn { ), ví dụ: xeHonda = {type: “AirBlade” .

Hóa ra vẫn còn 1 cách nữa, đó là dùng Object.create(). Bạn có thể xem chi tiết về cách dùng Object.create() ở đây, và một vài ưu điểm của nó ở đây.

Trong bài này, chúng ta tập trung vào Object.create(null) thôi. Thử luôn trong Chrome Devnhé:

var obj1 = Object.create(null),

obj2 = { ;

Soi thử xem từng object chứa gì?

Ảnh 7.

Lạ quá phải không!!! obj1 = Object.create(null) lại tạo ra 1 object trống rỗng không có tí properties nào. Bạn obj2 tưởng là cũng trống rỗng vậy mà vẫn có property tên là __proto__được sinh ra. Điều này nghĩa là sao?

• Tất cả các objects được sinh ra trong JavaScript đều có tối thiểu 1 property tên là __proto__ với các properties và methods bên trong được thừa kế từ 1 ông tổ tên là Object, chưa cần bạn khai báo thêm gì cả.

• Ngoại lệ xảy ra khi bạn truyền tham số null như cách trên, lúc này thì object của chúng ta thực sự trống rỗng bởi nó không thừa kế từ bất cứ cái gì.

Nếu đã trống rỗng như thế thì Object.create(null) sinh ra để làm gì?

Liệu mấy bác ngồi viết ECMAScript có rỗi việc không ạ? Bản thân tôi chưa có câu trả lời cho câu hỏi này. Nhưng David Walsh (một lập trình viên người Mỹ làm cho Mozilla) đã viết trong bài Object.create(null) như sau:

Object.create là một cách tuyệt vời để tạo object với prototype. Nhưng vấn đề là nó tạo ra __proto__ thừa kế mọi properties từ ông tổ Object, mà ông tổ này thì hoàn toàn có thể bị chọc ngoáy sửa đổi. Bạn sẽ làm gì nếu chỉ đơn thuần muốn tạo ra 1 object mới, và không cho nó bị thay đổi từ bên ngoài? Bạn có thể đạt được điều này với Object.create(null).

Xem đoạn code sau:

let obj = {

Object.prototype.sayHello = () => {console.log(“Hello”) ;

obj.sayHello() // return “Hello”

Theo Davis Walsh, anh không muốn tạo ra object tên là obj, rồi sau đó “bỗng dưng” obj lại mọc thêm 1 method sayHello chỉ bởi “ở đâu đó” người khác thay đổi ông tổ Object thông qua Object.prototype.

Một khi obj được tạo bằng Object.create(null), thì nó chẳng có prototype nữa để mà bị kế thừa từ Object. Thử nhé:

let obj2 = Object.create(null)

Object.prototype.sayILoveYou = () => {console.log(“I love you”)

obj2.sayILoveYou() // Uncaught TypeError: obj2.sayILoveYou is not a function

Và Dmitry Pashkevich (cũng là 1 lập trình viên người Mỹ đang làm cho Lucid Chart) trong bài Object.create(null) đã khẳng định thêm ý của David Walsh ở trên:

Đôi khi bạn muốn dùng một object JavaScript làm hash map (chỉ đơn thuần là lưu trữ dữ liệu), lúc đó bạn sẽ cần object tạo ra từ Object.create(null).

Object này khác biệt so với object tạo từ var data = {  ở chỗ bạn sẽ nhận được 1 object sạch, không kế thừa từ bất cừ thứ gì (tức là không có prototype). Ưu điểm? Không properties, không constructor, không toString, không hasOwnProperty, v.v. để bạn được tự do sử dụng các keys mà bạn cần.

Đương nhiên ngay cả với các objects tạo theo kiểu var data = {  thông thường thì bạn cũng không nên đụng đến các từ khóa đã được JavaScript sử dụng. Nhưng sẽ thế nào nếu bạn cần xây dựng một tập các phần tử (dạng map) với keys ngẫu nhiên được nhập vào bởi người dùng, hoặc từ những API của bên thứ 3? Chỗ này chính là nơi dụng võ của Object.create(null)!

Bên cạnh vụ Object.create(null), còn “map”, nó là gì?

Theo Mozilla Developer, object kiểu map chứa một hoặc nhiều các cặp “key-value”. Key và value có thể mang bất kỳ giá trị nào (cho dù là object hay các primitive values). Chi tiết về mục này ở đây. Do phần về map dài nên sẽ không được nói đến ở đây. Ngoài tài liệu bằng tiếng Anh trên, có 1 tài liệu tham khảo tiếng Việt trên freetuts tên là Collection Maps trong ES6 tương đối dễ hiểu.

ESlint đã cập nhật quy định trên ra sao?

Sau một hồi phân tích, chắc chúng ta đều đã dần nhận ra đoạn mô tả lý do ESlint chặn cách viết code thông thường. Tuy vậy, khi đọc phần thảo luận của ESlint team, thì quy định trên chỉ mới bắt đầu được đề xuất vào tháng 6 năm 2015. Có ý kiến phản đối, có ý kiến ủng hộ, và cũng phải mất gần 1 năm (tháng 5 năm 2016), quy định này mới chính thức thành hiện thực. Team ESlint đã trải qua quá trình trao đổi qua lại khá nhiều, thậm chí là phải bàn để thống nhất cả cái tên “no-prototype-builtins”.

Dưới đây là một trong những ý kiến cuối cùng tôi muốn trích lại đây để chuẩn bị gói lại bài viết này:

Toru Nagashima (mysticatea): Tôi tin rằng quy định này tương đối quan trọng bởi việc thừa kế từ null là một thứ đặc biệt trong JavaScript. Tôi đoán, những người vốn quen với lập trình trong các ngôn ngữ khác, nhưng không làm nhiều với JavaScript, sẽ khó có thể tưởng tượng về khả năng không tồn tại của obj.hasOwnProperty. Một vài thư viện phổ biến (như querystring) vẫn đang dùng Object.create(null).

Tóm lại

Mỗi objects khi được tạo ra, bên cạnh những methods/properties do người dùng tạo ra (gọi là “OwnProperties”), thì còn có sẵn những methods/properties mà JavaScript gán cho nó (chính là những prototype.properties). Giống như một đứa trẻ mới sinh ra, tuy bố mẹ không dạy cho nó khóc – ăn – ngủ – đái dầm – ị đùn, thì bản năng con người vẫn cho nó các hành động như vậy. Còn trong JavaScript, vừa được tạo ra thì mỗi object đã mang trong mình các methods kiểu như .hasOwnProperties(), isPrototypeOf(), .v.v.

Tuy vậy, có những objects mà lập trình viên cố tình tạo ra để nó không có những methods/properties có sẵn nói trên (tức là không có cả .hasOwnProperties(), isPrototypeOf(), .v.v. ). Có người gọi đây là những objects “clean” (sạch), “naked” (trần chuồng/ nuy), v.v. Các object đó được tạo từ Object.create(null), không hề có Object.prototype.

Một khi objects đã “clean”, đã “naked” kiểu trên, thì gọi methods như .hasOwnProperties()hay isPrototypeOf() làm sao được? sẽ bị báo lỗi ngay.

ESlint đã tạo ra một quy định để ngăn ngừa lập trình viên sử dụng những methods kia để tránh gặp lỗi.

Nếu đã bật ESlint khi viết code, hãy nhớ tránh dùng:

– Object.hasOwnProperty(),

– Object.isPrototypeOf(),

– Object.propertyIsEnumerable(),

mà nên sử dụng:

– Object.prototype.hasOwnProperty.call( ),

– Object.prototype.isPrototypeOf.call( ),

– Object.prototype.propertyIsEnumerable.call( );

Để hiểu được những gì liên quan đến quy đình này thì cần hiểu rất nhiều thứ cơ bản khác như Object, prototype, các methods để kiểm tra sự tồn tại của property nào đó trong object (như dùng hasOwnProperties, dùng toán tử IN), hiểu về map, v.v. Từ đó mới thấy là kiến thức nhiều chỗ hổng lởm chởm như thế nào.

Post Views: 121
Previous Post

Code Monk(ey): Kiểm tra Array trong JavaScript

Next Post

Prototype trong JavaScript

Related Posts

Sửa Nhanh Lỗi Laptop Windows 10 Sạc Pin Không Vào 60951215e059b.png
Phần cứng

Sửa nhanh lỗi laptop Windows 10 sạc pin không vào

11/05/2022
Làm Thế Nào để Xóa Một Phân Vùng Trên ổ đĩa Cứng Windows? 60951232be65c.png
Phần cứng

Làm thế nào để xóa một phân vùng trên ổ đĩa cứng Windows?

11/05/2022
Test Pin Laptop, Cách Kiểm Tra Pin Laptop đang ở Mức Nào Mà Không Cần Cài Phần Mềm 6095123831651.png
Phần cứng

Test pin laptop, cách kiểm tra pin laptop đang ở mức nào mà không cần cài phần mềm

11/05/2022
Hướng Dẫn Xử Lý Khi Key Bàn Phím Laptop Bị Hỏng 6095121ca32df.png
Phần cứng

Hướng dẫn xử lý khi key bàn phím laptop bị hỏng

11/05/2022
Nên Dùng Súng Loại Nào Trong Chiến Dịch Huyền Thoại? 6094aaf17f1da.png
Phần Mềm

Nên dùng súng loại nào trong Chiến Dịch Huyền Thoại?

07/05/2022
Hướng Dẫn Cài đặt Wtfast để Giảm Ping Khi Chơi Game Online, Khi đứt Cáp 6094aae16ee4b.png
Phần Mềm

Hướng dẫn cài đặt WTFast để giảm ping khi chơi game online, khi đứt cáp

07/05/2022
Next Post
Prototype Trong Javascript 60902d0a8d05a.jpeg

Prototype trong JavaScript

Bài mới nhất

Dịch Vụ Thiết Kế Website Tại Hải Dương Chuyên Nghiệp, ấn Tượng Và Uy Tín 612d25752b14f.png

Dịch vụ thiết kế website tại Hải Dương chuyên nghiệp, ấn tượng và uy tín

06/05/2025
Top Công Ty Thiết Kế Website Tại Biên Hòa Chuyên Nghiệp, Chuẩn Seo 612d259494e93.jpeg

Top công ty thiết kế website tại Biên Hòa chuyên nghiệp, chuẩn SEO

06/05/2025
Top Công Ty Thiết Kế Website Tại Vinh – Nghệ An Uy Tín 612d259a9cae3.jpeg

Top công ty thiết kế website tại Vinh – Nghệ An uy tín

05/05/2025
Top 10 Công Ty Thiết Kế Website Tại Nha Trang Chuyên Nghiệp 612d0a9ad018b.jpeg

Top 10 công ty thiết kế website tại Nha Trang chuyên nghiệp

05/05/2025
Các Dịch Vụ Thiết Kế Website Tại Vĩnh Phúc Chuyên Nghiệp, Uy Tín Nhất 612d0a91e63af.jpeg

Các dịch vụ thiết kế website tại Vĩnh Phúc chuyên nghiệp, uy tín nhất

04/05/2025

Danh mục

  • Android
  • Bảo mật máy tính
  • Bảo mật, Antivirus
  • Chuyện công nghệ
  • Deep Learning
  • Development
  • Dịch vụ công trực tuyến
  • Dịch vụ nhà mạng
  • Giải pháp bảo mật
  • Hệ thống
  • Hệ thống
  • iPhone
  • Kiến thức bảo mật
  • Kiến thức cơ bản phổ thông
  • Kiến thức Marketing căn bản
  • Kiến thức tổng hợp
  • Lập trình
  • Linux
  • Linux OS
  • macOS
  • Mail Server
  • Mạng LAN – WAN
  • Máy ảo
  • Máy chủ
  • ms excel
  • ms-powerpoint
  • Nền tảng điện toán đám mây
  • Phần cứng
  • Phần Mềm
  • Quản trị hệ thống
  • Raspberry Pi
  • Sửa lỗi máy tính
  • Tăng tốc máy tính
  • Thủ thuật
  • Thủ thuật SEO
  • Thủ thuật Wifi
  • Tiện ích hệ thống
  • Tin học văn phòng
  • Tin tức
  • Uncategorized
  • Ứng dụng
  • Website
  • Windows Server 2012

Thẻ

#app #chatbot #chatbot tự động #CRM #Kiến thức cơ bản #Techblog #Thiết kế website Android apple CPU Email Marketing Google Google Drive hacker HTML hàm python hàm python có sẵn hình nền hình nền máy tính học css học python học SQL ios iphone iphone 12 iPhone X macos Microsoft mssql MS SQL Server ngôn ngữ lập trình python Raspberry Pi Samsung smartphone SQL SQL Server tham số trong C thủ thuật windows 10 tài liệu python windows windows 10 YouTube điện thoại thông minh ứng dụng
  • About
  • Advertise
  • Privacy & Policy
  • Contact

© 2022 Pha Le Solution

No Result
View All Result
  • Home

© 2022 Pha Le Solution