Sự khác biệt giữa các đối tượng gốc và các đối tượng chủ là gì?


90

Cái sau có chỉ đơn giản là tham chiếu đến các đối tượng hàm không trực quan được tạo bởi một hàm tạo tùy chỉnh (ví dụ: var bird1 = new Bird ();) không?


2
Đối tượng gốc được xác định trong đặc tả ECMAScript, đối tượng chủ thì không.
Šime Vidas

6
Ví dụ, new Image()một phần tử DOM - giả sử - là một đối tượng máy chủ.

@ ŠimeVidas: Có lý do nào bạn để lại nhận xét mâu thuẫn với câu trả lời của bạn không?
user113716,

@ Ӫ _._ Ӫ Đó là điều của tôi bây giờ:)
Šime Vidas.

1
@ ŠimeVidas: Nhận xét của bạn nói rằng các đối tượng lưu trữ không được xác định trong đặc tả ECMAScript . Câu trả lời của bạn cho biết "Định nghĩa cho cả hai đều nằm trong phần xác định ECMAScript" .
user113716,

Câu trả lời:


133

Cả hai thuật ngữ đều được định nghĩa trong đặc tả ECMAScript:

đối tượng bản địa

đối tượng trong triển khai ECMAScript có ngữ nghĩa được xác định đầy đủ bởi đặc tả này chứ không phải bởi môi trường chủ.

CHÚ THÍCH: Các đối tượng gốc tiêu chuẩn được định nghĩa trong tiêu chuẩn này. Một số đối tượng gốc được tích hợp sẵn; những phần khác có thể được xây dựng trong quá trình thực hiện chương trình ECMAScript.

Nguồn: http://es5.github.com/#x4.3.6

vật chủ

đối tượng do môi trường máy chủ cung cấp để hoàn thành môi trường thực thi của ECMAScript.

LƯU Ý Bất kỳ đối tượng nào không phải là bản địa đều là đối tượng chủ.

Nguồn: http://es5.github.com/#x4.3.8


Một vài ví dụ:

Đối tượng Quê quán: Object(constructor), Date, Math, parseInt, eval, phương pháp chuỗi như indexOfreplace, phương pháp mảng, ...

Đối tượng máy chủ (giả sử môi trường trình duyệt): window, document, location, history, XMLHttpRequest, setTimeout, getElementsByTagName, querySelectorAll, ...


8
cho anh ta một số ví dụ quá, đối tượng bẩm sinh: Array, String .., đối tượng chủ: cửa sổ ...
Poelinca Dorin

1
những gì về một người giám sát tùy chỉnh? ví dụ, ví dụ chim trong bài viết của tôi
ppecher

2
@ ŠimeVidas: "Vậy thì nó là một đối tượng chủ." Điều đó không chính xác. Xem định nghĩa của host objectđược mô tả trong câu trả lời này .
user113716

1
ŠimeVidas: Nhưng đặc tả cho biết 'Giá trị của thuộc tính bên trong [[Class]] của đối tượng chủ có thể là bất kỳ giá trị Chuỗi nào ngoại trừ một trong các "Đối số", "Mảng", "Boolean", "Ngày", "Lỗi", "Hàm", "JSON", "Toán học", "Số", "Đối tượng" , "RegExp" và "Chuỗi". ' Thuộc tính [[Class]] nội bộ của đối tượng Bird của bạn sẽ được 'Object'hoặc được trình bày Object.prototype.toStringdưới dạng '[object Object]'.
user113716,

2
@ ŠimeVidas, tôi không đồng ý, nếu Birdlà một hàm do người dùng định nghĩa, thì ngữ nghĩa của nó được "xác định đầy đủ" bởi đặc tả ES (cách các đối tượng hàm hoạt động, cách chúng được tạo, thực thi, sử dụng với newtoán tử, v.v., v.v.) thì đó là đối tượng bẩm sinh ... tôi có thể thả một câu trả lời ...
Christian C. Salvadó

28

Sẽ rõ ràng hơn nếu chúng ta phân biệt giữa ba loại đối tượng:

Built-in đối tượng : String, Math, RegExp, Object, Functionvv - cốt lõi được xác định trước đối tượng luôn luôn có sẵn trong JavaScript. Được xác định trong thông số ECMAScript.

Đối tượng lưu trữ : các đối tượng như window,, XmlHttpRequestnút DOM, v.v., được cung cấp bởi môi trường trình duyệt. Chúng khác biệt với các đối tượng tích hợp sẵn bởi vì không phải môi trường nào cũng có các đối tượng chủ giống nhau. Nếu JavaScript chạy bên ngoài trình duyệt, chẳng hạn như ngôn ngữ kịch bản phía máy chủ như trong Node.js, các đối tượng máy chủ lưu trữ khác sẽ khả dụng.

Đối tượng người dùng : các đối tượng được định nghĩa trong mã JavaScript. Vì vậy, 'Bird' trong ví dụ của bạn sẽ là một đối tượng người dùng.

Đặc tả JavaScript nhóm các đối tượng tích hợp và đối tượng người dùng lại với nhau dưới dạng các đối tượng gốc . Đây là cách sử dụng không chính thống của thuật ngữ "gốc", vì các đối tượng người dùng rõ ràng được triển khai bằng JavaScript trong khi các bản cài sẵn rất có thể được triển khai bằng một ngôn ngữ khác, giống như các đối tượng máy chủ. Nhưng từ quan điểm của đặc tả JavaScript, cả nội trang và đối tượng người dùng đều có nguồn gốc từ JavaScript vì chúng được định nghĩa trong đặc tả JavaScript, trong khi các đối tượng máy chủ thì không.


Các đối tượng gốc đề cập đến những đối tượng được tạo ra bằng cách triển khai javascript (engine). Sự khác biệt giữa các đối tượng cài sẵn và các đối tượng gốc khác (đối tượng người dùng) là các đối tượng cũ hiện diện kể từ khi chương trình javascript bắt đầu tuân thủ các quy tắc ECMA có liên quan. Kể từ ECMA6 (<ECMA6 ecma-international.org/publications/files/ECMA-ST/… ), nó không sử dụng thuật ngữ trên để phân loại đối tượng. Tham khảo câu trả lời của tôi dưới đây.
jaaw

17

Đây là hiểu biết của tôi về thông số kỹ thuật.

Điều này:

var bird = new Bird();

... dẫn đến một Đối tượng gốc chỉ đơn giản là được tạo ra bằng cách sử dụng newtoán tử.

Các đối tượng gốc có thuộc tính [[Class]] nội bộ của một trong các thuộc tính sau:

"Đối số", "Mảng", "Boolean", "Ngày", "Lỗi", "Hàm", "JSON", "Toán", "Số", "Đối tượng", "RegExp" và "Chuỗi" .

Đối với bạn, bird1nó sẽ là:

"Vật"

Giống như nếu bạn tạo một hàm:

function my_func() {
    // ...
}

... my_funckhông được định nghĩa trong ECMAScript, nhưng nó vẫn là một đối tượng gốc với [[Class]] nội bộ:

"Chức năng"

Đối tượng chủ là một đối tượng được cung cấp bởi môi trường nhằm phục vụ một mục đích cụ thể cho môi trường đó không được xác định trong đặc tả.

Ví dụ:

var divs = document.getElementsByTagName('div')

Đối tượng được tham chiếu bởi divsNodeList , được tích hợp vào môi trường theo cách mà nó có cảm giác giống như một đối tượng JavaScript thông thường, nhưng nó không được định nghĩa ở bất kỳ đâu bởi đặc tả.

Thuộc tính [[Class]] nội bộ của nó là:

"NodeList"

Điều này cung cấp cho các nhà thiết kế triển khai sự linh hoạt trong việc điều chỉnh việc triển khai theo nhu cầu cụ thể của môi trường.

Có các yêu cầu của các đối tượng máy chủ được xác định trong suốt thông số kỹ thuật.


2
+1, tôi đồng ý với bạn, birdBirdcác đối tượng gốc , chúng là một hàm do người dùng xác định ( Bird) và một đối tượng ( bird) được tạo bằng cách sử dụng hàm như một phương thức khởi tạo, tất cả các ngữ nghĩa của điều này được xác định trên spec. Về đối tượng sở tại, không dựa quá nhiều vào các [[Class]]tài sản nội bộ, ví dụ như window.alert"Function"như giá trị của nó [[Class]]sở hữu hầu hết các triển khai, trên IE nó có "Object", và nó vẫn là một đối tượng máy chủ ...
Christian C. Salvadó

Cảm ơn @CMS. Vâng, tôi không có ý quá chú trọng vào việc sử dụng nội bộ [[Class]]. Thay vì chỉ sử dụng nó như một cái nhìn hữu hình về cách những người triển khai đã diễn giải các loại đối tượng khác nhau. Vì vậy, sau đó window.alertcó một nội [[Class]]các "Function"sẽ có vẻ là một sự vi phạm của ES 5?
user113716

Tôi đang cố gắng xem hành động ain này, nhưng nếu tôi nhận được kiểu chữ div đó divs/NodeList, tôi nhận được một object. Tôi đoán là tôi chưa hiểu điều này, nhưng điều đó có làm cho nó trở thành một đối tượng gốc không?
Mark B

Điều này là hữu ích . Bắt tất cả mọi thứ trong windowchương trình tất cả các đối tượng máy chủ
Mark B

Bird không phải là một đối tượng gốc vì giao diện của nó không được mô tả đầy đủ trong tiêu chuẩn ECMASCript. Nó thực sự đơn giản. Đối tượng là bản địa và Chuỗi là bản nguyên, nhưng các đối tượng do người dùng xác định hoặc do máy chủ xác định không phải là bản gốc.
Scott Marcus

3

Không thể thấy câu trả lời thuyết phục cho câu hỏi var bird1 = new Bird();là đối tượng bản địa hay vật chủ. Giả sử Bird là một chức năng do người dùng xác định, một đối tượng gốc không được tích hợp sẵn sẽ được tạo theo http://es5.github.io/#x13.2 bằng cách triển khai javascript. Ngược lại, cài sẵn gốccác đối tượng sẽ hiện diện kể từ khi bắt đầu một chương trình javascript (chẳng hạn như Đối tượng và nhiều đối tượng khác). Sự khác biệt giữa đối tượng gốc và đối tượng máy chủ là đối tượng trước được tạo ra bởi việc triển khai javascript và đối tượng sau được cung cấp bởi môi trường máy chủ. Do đó, thuộc tính nội bộ [[class]] của đối tượng máy chủ có thể khác với thuộc tính được sử dụng bởi các đối tượng tích hợp (tức là "Đối số", "Mảng", "Boolean", "Ngày", "Lỗi", "Hàm", " JSON "," Math "," Number "," Object "," RegExp "và" String ").

Ngoài ra, đáng chú ý là ECMA6 http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf không sử dụng thuật ngữ native và host object nữa. Thay vào đó, nó xác định các loại đối tượng bên dưới, với các giải thích rõ ràng hơn về hành vi dự định của chúng.

4.3.6 đối tượng thông thường

đối tượng có hành vi mặc định cho các phương thức nội bộ thiết yếu phải được hỗ trợ bởi tất cả các đối tượng

4.3.7 vật thể lạ

đối tượng không có hành vi mặc định cho một hoặc nhiều phương thức bên trong thiết yếu phải được hỗ trợ bởi tất cả các đối tượng CHÚ THÍCH Bất kỳ đối tượng nào không phải là đối tượng thông thường đều là đối tượng ngoại lai.

4.3.8 đối tượng tiêu chuẩn

đối tượng có ngữ nghĩa được xác định bởi đặc tả này

4.3.9 đối tượng tích hợp

đối tượng do triển khai ECMAScript chỉ định và cung cấp


3

Ngoài các câu trả lời khác liên quan đến Đối tượng Máy chủ.

Đối tượng chủ là cụ thể cho một môi trường. Vì vậy, bên cạnh các đối tượng máy chủ của trình duyệt, cũng có các đối tượng cụ thể cho nodejs.

Vì lợi ích của ví dụ, trước tiên hãy bắt đầu với các đối tượng Chuẩn như được định nghĩa trong Javascript. Sau đó là các đối tượng chung cho Trình duyệt / DOM. Node có các Đối tượng của riêng nó.

  1. Ví dụ về đối tượng tích hợp sẵn trong Javascript chuẩn :

  2. Đối tượng Máy chủ Tài liệu Ví dụ về Mô hình Đối tượng :

  3. Đối tượng lưu trữ trong Node.js :


1

Xem xét ba đối tượng: Host, Native, Custom.

Đối tượng Máy chủ được tạo ra bởi môi trường và là môi trường cụ thể. Môi trường được biết đến nhiều nhất sẽ là một trình duyệt web nhưng có thể là một nền tảng khác. Các đối tượng máy chủ được tạo trong trình duyệt web có thể là đối tượng cửa sổ hoặc tài liệu. Thông thường, một trình duyệt sử dụng API để tạo Đối tượng máy chủ để phản ánh Mô hình đối tượng tài liệu sang JavaScript. (Trình duyệt web có các Công cụ JavaScript khác nhau thực hiện điều này) Đối tượng máy chủ lưu trữ được tạo tự động ngay khi trang hiển thị trong trình duyệt.

Một Native Object được tạo bởi nhà phát triển bằng cách sử dụng các lớp JavaScript được xác định trước. Đối tượng gốc nằm trong kịch bản viết của bạn.

Hơn nữa, một Đối tượng tùy chỉnh được tạo ra bởi nhà phát triển từ một lớp tùy chỉnh (không được xác định trước hoặc được xác định trước một phần).


0

Đối tượng gốc là các đối tượng tuân theo các thông số kỹ thuật, tức là "đối tượng tiêu chuẩn".

Đối tượng máy chủ lưu trữ là các đối tượng mà trình duyệt (hoặc môi trường thời gian chạy khác như Node) cung cấp.

Hầu hết các đối tượng máy chủ là các đối tượng gốc và bất cứ khi nào bạn khởi tạo một thứ gì đó bằng cách sử dụng new, bạn có thể chắc chắn 99,99% rằng đó là một đối tượng gốc, trừ khi bạn gây rối với các đối tượng máy chủ kỳ lạ.

Khái niệm này đã được đưa ra do sự hiện diện của các đối tượng rất kỳ lạ trong IE (và các trình duyệt cũ khác?) . Ví dụ:

typeof document.all == "undefined"; // true
document.all.myElementId; // object

Khi nhìn thấy điều này, mọi người sẽ đồng ý rằng document.allrõ ràng là "không chuẩn" và do đó là một đối tượng máy chủ lưu trữ không phải là bản địa .

Vậy tại sao không gọi các đối tượng gốc là đối tượng chuẩn ngay từ đầu? Đơn giản: xét cho cùng, tài liệu Standard (!) Cũng nói về các đối tượng không phải là bản địa, và việc gọi chúng là phi tiêu chuẩn sẽ dẫn đến một nghịch lý.

Lần nữa:

  • gốc == "tiêu chuẩn"
  • host == do trình duyệt hoặc Node cung cấp hoặc…
  • hầu hết các đối tượng máy chủ đều là bản địa và tất cả các đối tượng không phải máy chủ cũng là bản gốc

Bạn đã đi chệch khỏi đường ray một chút ở đó. "Hầu hết các đối tượng máy chủ là bản địa" là không chính xác. Trên thực tế, theo định nghĩa TẤT CẢ các đối tượng máy chủ KHÔNG phải là bản địa. Bản ngữ chắc chắn có nghĩa là "tiêu chuẩn", nhưng nó có nghĩa là tiêu chuẩn trong đặc tả ngôn ngữ, không phải tiêu chuẩn theo nghĩa khác thường. JavaScript (ECMASCript) xác định một số giao diện / API được triển khai bởi trình duyệt và các máy chủ khác, chẳng hạn như: Chuỗi, Ngày, MATH, Boolean, Số, JSON và XmlHTTP. Các đối tượng này khả dụng vì máy chủ triển khai công cụ tuân thủ ECMAScript và đáp ứng tiêu chuẩn ECMA.
Scott Marcus

0

Điều này có thể là quá mức cần thiết, nhưng vì đơn giản, một đối tượng gốc là một đối tượng tồn tại và có thể sử dụng được trong bất kỳ môi trường nào triển khai công cụ tuân thủ ECMAScript. Đây thường (nhưng không phải luôn luôn) là một trình duyệt.

Vì vậy, ví dụ như Internet Explorer hoặc Google Chrome của bạn không cung cấp đối tượng Chuỗi cho bạn. Lý do bạn có thể sử dụng đối tượng String là vì nó là "bản địa" (được tích hợp sẵn) cho chính ngôn ngữ JavaScript.

Tuy nhiên, nếu bạn muốn tạo một cửa sổ bật lên, bạn sẽ cần sử dụng đối tượng cửa sổ. Đối tượng cửa sổ được cung cấp bởi chính phần mềm trình duyệt, do đó, nó không phải là nguồn gốc của JavaScript, nhưng nó là một phần của "Mô hình đối tượng trình duyệt" hoặc BOM.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.