Các sắc thái của thừa kế nguyên mẫu / nguyên mẫu trong AngularJS là gì?


1028

Các API trang Scope tham khảo nói:

Một phạm vi có thể kế thừa từ một phạm vi cha.

Các nhà phát triển Hướng dẫn trang Scope nói:

Một phạm vi (nguyên mẫu) kế thừa các thuộc tính từ phạm vi cha của nó.

  • Vì vậy, một phạm vi con luôn luôn kế thừa nguyên mẫu từ phạm vi cha mẹ của nó?
  • Có ngoại lệ không?
  • Khi nó kế thừa, nó có luôn là kế thừa nguyên mẫu JavaScript bình thường không?

Câu trả lời:


1741

Câu trả lời nhanh :
Một phạm vi con thường được kế thừa nguyên mẫu từ phạm vi cha của nó, nhưng không phải lúc nào cũng vậy. Một ngoại lệ cho quy tắc này là một chỉ thị với scope: { ... }- điều này tạo ra một phạm vi "cô lập" không kế thừa nguyên mẫu. Cấu trúc này thường được sử dụng khi tạo một lệnh "thành phần có thể tái sử dụng".

Đối với các sắc thái, kế thừa phạm vi thường là đơn giản ... cho đến khi bạn cần liên kết dữ liệu 2 chiều (nghĩa là các phần tử biểu mẫu, mô hình ng) trong phạm vi con. Ng-repeat, ng-switch và ng-include có thể khiến bạn vấp ngã nếu bạn cố gắng liên kết với một nguyên thủy (ví dụ: số, chuỗi, boolean) trong phạm vi cha từ bên trong phạm vi con. Nó không hoạt động theo cách mà hầu hết mọi người mong đợi nó sẽ hoạt động. Phạm vi con có thuộc tính riêng của nó ẩn / đổ bóng thuộc tính cha mẹ cùng tên. Cách giải quyết của bạn là

  1. xác định các đối tượng trong cha mẹ cho mô hình của bạn, sau đó tham chiếu một thuộc tính của đối tượng đó trong con: ParentObj.someProp
  2. sử dụng $ Parent.parentScopeProperty (không phải lúc nào cũng có thể, nhưng dễ hơn 1. khi có thể)
  3. định nghĩa một hàm trên phạm vi cha và gọi nó từ con (không phải lúc nào cũng có thể)

Phát triển AngularJS mới thường không nhận ra rằng ng-repeat, ng-switch, ng-view, ng-includeng-iftất cả tạo phạm vi con mới, vì vậy vấn đề thường xuất hiện khi các chỉ thị có liên quan. (Xem ví dụ này để minh họa nhanh về vấn đề.)

Vấn đề này với người nguyên thủy có thể dễ dàng tránh được bằng cách tuân theo "thực tiễn tốt nhất" luôn luôn có '.' trong các mô hình ng của bạn - xem giá trị 3 phút. Misko chứng minh vấn đề ràng buộc nguyên thủy với ng-switch.

Có một '.' trong các mô hình của bạn sẽ đảm bảo rằng kế thừa nguyên mẫu đang hoạt động. Vì vậy, sử dụng

<input type="text" ng-model="someObj.prop1">

<!--rather than
<input type="text" ng-model="prop1">`
-->


Câu trả lời dài :

Kế thừa nguyên mẫu JavaScript

Cũng được đặt trên wiki AngularJS: https://github.com/angular/angular.js/wiki/Under Hiểu-Sames

Điều quan trọng trước tiên là phải có hiểu biết vững chắc về kế thừa nguyên mẫu, đặc biệt nếu bạn đến từ nền tảng phía máy chủ và bạn quen thuộc hơn với kế thừa lớp ical. Vì vậy, hãy xem xét lại đầu tiên.

Giả sử ParentScope có các thuộc tính aString, aNumber, anArray, anObject và aFunction. Nếu childScope được kế thừa nguyên mẫu từ ParentScope, chúng ta có:

thừa kế nguyên mẫu

(Lưu ý rằng để tiết kiệm không gian, tôi hiển thị anArrayđối tượng dưới dạng một đối tượng màu xanh lam duy nhất với ba giá trị của nó, chứ không phải là một đối tượng màu xanh duy nhất có ba chữ màu xám riêng biệt.)

Nếu chúng tôi cố gắng truy cập một thuộc tính được xác định trên ParentScope từ phạm vi con, trước tiên JavaScript sẽ tìm trong phạm vi con, không tìm thấy thuộc tính, sau đó tìm trong phạm vi được kế thừa và tìm thuộc tính. (Nếu nó không tìm thấy thuộc tính trong ParentScope, nó sẽ tiếp tục chuỗi nguyên mẫu ... đến tận phạm vi gốc). Vì vậy, đây là tất cả sự thật:

childScope.aString === 'parent string'
childScope.anArray[1] === 20
childScope.anObject.property1 === 'parent prop1'
childScope.aFunction() === 'parent output'

Giả sử sau đó chúng ta làm điều này:

childScope.aString = 'child string'

Chuỗi nguyên mẫu không được tham khảo và thuộc tính aString mới được thêm vào childScope. Thuộc tính mới này ẩn / làm mờ thuộc tính ParentScope có cùng tên. Điều này sẽ trở nên rất quan trọng khi chúng ta thảo luận về ng-repeat và ng-gộp bên dưới.

cất giấu tài sản

Giả sử sau đó chúng ta làm điều này:

childScope.anArray[1] = '22'
childScope.anObject.property1 = 'child prop1'

Chuỗi nguyên mẫu được tham khảo vì các đối tượng (anArray và anObject) không được tìm thấy trong childScope. Các đối tượng được tìm thấy trong ParentScope và các giá trị thuộc tính được cập nhật trên các đối tượng ban đầu. Không có thuộc tính mới nào được thêm vào childScope; không có đối tượng mới được tạo ra. (Lưu ý rằng trong các mảng và hàm JavaScript cũng là các đối tượng.)

theo chuỗi nguyên mẫu

Giả sử sau đó chúng ta làm điều này:

childScope.anArray = [100, 555]
childScope.anObject = { name: 'Mark', country: 'USA' }

Chuỗi nguyên mẫu không được tham khảo và phạm vi con có hai thuộc tính đối tượng mới ẩn / tạo bóng các thuộc tính đối tượng ParentScope có cùng tên.

giấu tài sản nhiều hơn

Hành trình:

  • Nếu chúng ta đọc childScope.propertyX và childScope có propertyX, thì chuỗi nguyên mẫu không được tham khảo.
  • Nếu chúng ta đặt childScope.propertyX, chuỗi nguyên mẫu không được tham khảo.

Một kịch bản cuối cùng:

delete childScope.anArray
childScope.anArray[1] === 22  // true

Chúng tôi đã xóa thuộc tính childScope trước, sau đó khi chúng tôi cố gắng truy cập lại tài sản đó, chuỗi nguyên mẫu được tham khảo.

sau khi xóa tài sản con


Kế thừa phạm vi góc

Các ứng cử viên:

  • Sau đây tạo phạm vi mới và kế thừa nguyên mẫu: ng-repeat, ng-include, ng-switch, ng-controller, directive with scope: true, directive with transclude: true.
  • Sau đây tạo ra một phạm vi mới không kế thừa nguyên mẫu: chỉ thị với scope: { ... }. Điều này tạo ra một phạm vi "cô lập" thay thế.

Lưu ý, theo mặc định, các lệnh không tạo phạm vi mới - tức là mặc định là scope: false.

bao gồm

Giả sử chúng ta có trong bộ điều khiển của mình:

$scope.myPrimitive = 50;
$scope.myObject    = {aNumber: 11};

Và trong HTML của chúng tôi:

<script type="text/ng-template" id="/tpl1.html">
<input ng-model="myPrimitive">
</script>
<div ng-include src="'/tpl1.html'"></div>

<script type="text/ng-template" id="/tpl2.html">
<input ng-model="myObject.aNumber">
</script>
<div ng-include src="'/tpl2.html'"></div>

Mỗi ng-gộp tạo ra một phạm vi con mới, mà nguyên mẫu kế thừa từ phạm vi cha.

ng-bao gồm phạm vi trẻ em

Nhập (giả sử "77") vào hộp văn bản đầu vào đầu tiên làm cho phạm vi con nhận được một thuộc tính myPrimitivephạm vi mới ẩn / đổ bóng thuộc tính phạm vi cha có cùng tên. Đây có lẽ không phải là những gì bạn muốn / mong đợi.

bao gồm một nguyên thủy

Nhập (giả sử, "99") vào hộp văn bản đầu vào thứ hai không dẫn đến một thuộc tính con mới. Vì tpl2.html liên kết mô hình với thuộc tính đối tượng, nên thừa kế nguyên mẫu sẽ khởi động khi ngModel tìm kiếm đối tượng myObject - nó tìm thấy nó trong phạm vi cha.

bao gồm một đối tượng

Chúng ta có thể viết lại mẫu đầu tiên để sử dụng $ Parent, nếu chúng ta không muốn thay đổi mô hình của mình từ nguyên thủy thành một đối tượng:

<input ng-model="$parent.myPrimitive">

Nhập (giả sử, "22") vào hộp văn bản đầu vào này không dẫn đến một thuộc tính con mới. Mô hình hiện được liên kết với một thuộc tính của phạm vi cha (vì $ cha là thuộc tính phạm vi con tham chiếu phạm vi cha).

bao gồm với cha mẹ $

Đối với tất cả các phạm vi (nguyên mẫu hoặc không), Angular luôn theo dõi mối quan hệ cha-con (tức là hệ thống phân cấp), thông qua các thuộc tính phạm vi $ Parent, $$ childHead và $$ childTail. Tôi thường không hiển thị các thuộc tính phạm vi này trong các sơ đồ.

Đối với các kịch bản không tham gia vào các phần tử biểu mẫu, một giải pháp khác là xác định hàm trên phạm vi cha để sửa đổi nguyên hàm. Sau đó, đảm bảo đứa trẻ luôn gọi hàm này, sẽ có sẵn cho phạm vi con do thừa kế nguyên mẫu. Ví dụ,

// in the parent scope
$scope.setMyPrimitive = function(value) {
     $scope.myPrimitive = value;
}

Dưới đây là một câu đố mẫu sử dụng phương pháp "hàm cha" này. (Câu đố được viết như một phần của câu trả lời này: https://stackoverflow.com/a/14104318/215945 .)

Xem thêm https://stackoverflow.com/a/13782671/215945https://github.com/angular/angular.js/issues/1267 .

ng-chuyển

thừa kế phạm vi ng-switch hoạt động giống như ng-gộp. Vì vậy, nếu bạn cần liên kết dữ liệu 2 chiều với một nguyên thủy trong phạm vi cha, hãy sử dụng $ cha hoặc thay đổi mô hình thành một đối tượng và sau đó liên kết với một thuộc tính của đối tượng đó. Điều này sẽ tránh phạm vi con ẩn / bóng của các thuộc tính phạm vi cha.

Xem thêm AngularJS, phạm vi ràng buộc của trường hợp chuyển đổi?

lặp lại

Ng-lặp lại hoạt động một chút khác nhau. Giả sử chúng ta có trong bộ điều khiển của mình:

$scope.myArrayOfPrimitives = [ 11, 22 ];
$scope.myArrayOfObjects    = [{num: 101}, {num: 202}]

Và trong HTML của chúng tôi:

<ul><li ng-repeat="num in myArrayOfPrimitives">
       <input ng-model="num">
    </li>
<ul>
<ul><li ng-repeat="obj in myArrayOfObjects">
       <input ng-model="obj.num">
    </li>
<ul>

Đối với mỗi mục / lần lặp, ng-repeat tạo ra một phạm vi mới, được kế thừa nguyên mẫu từ phạm vi cha, nhưng nó cũng gán giá trị của mục đó cho một thuộc tính mới trên phạm vi con mới . (Tên của thuộc tính mới là tên của biến vòng lặp.) Đây là mã nguồn Angular cho ng-repeat thực sự là:

childScope = scope.$new();  // child scope prototypically inherits from parent scope
...
childScope[valueIdent] = value;  // creates a new childScope property

Nếu mục là một nguyên thủy (như trong myArrayOfPrimologists), về cơ bản, một bản sao của giá trị được gán cho thuộc tính phạm vi con mới. Thay đổi giá trị của thuộc tính phạm vi con (nghĩa là sử dụng mô hình ng, do đó phạm vi con num) không thay đổi mảng tham chiếu phạm vi cha. Vì vậy, trong lần lặp lại đầu tiên ở trên, mỗi phạm vi con có một thuộc numtính độc lập với mảng myArrayOfPrimologists:

ng-lặp lại với nguyên thủy

Điều này lặp lại sẽ không hoạt động (như bạn muốn / mong đợi nó). Nhập vào các hộp văn bản sẽ thay đổi các giá trị trong các hộp màu xám, chỉ hiển thị trong phạm vi con. Những gì chúng ta muốn là cho các đầu vào ảnh hưởng đến mảng myArrayOfPrimologists, không phải là một thuộc tính nguyên thủy phạm vi con. Để thực hiện điều này, chúng ta cần thay đổi mô hình thành một mảng các đối tượng.

Vì vậy, nếu mục là một đối tượng, tham chiếu đến đối tượng ban đầu (không phải là bản sao) được gán cho thuộc tính phạm vi con mới. Thay đổi giá trị của thuộc tính phạm vi con (nghĩa là sử dụng mô hình ng, do đó obj.num) sẽ thay đổi đối tượng tham chiếu phạm vi cha. Vì vậy, trong lần lặp lại thứ hai ở trên, chúng ta có:

lặp lại với các đối tượng

(Tôi tô màu một dòng màu xám để nó rõ ràng nơi nó sẽ đi.)

Điều này hoạt động như mong đợi. Nhập vào các hộp văn bản sẽ thay đổi các giá trị trong các hộp màu xám, có thể nhìn thấy được cho cả phạm vi con và cha.

Xem thêm Khó khăn với ng-model, ng-repeat và đầu vàohttps://stackoverflow.com/a/13782671/215945

bộ điều khiển ng

Các bộ điều khiển lồng nhau sử dụng bộ điều khiển ng dẫn đến sự kế thừa nguyên mẫu bình thường, giống như ng-gộp và ng-switch, do đó các kỹ thuật tương tự được áp dụng. Tuy nhiên, "hai bộ điều khiển được coi là hình thức xấu để chia sẻ thông tin thông qua kế thừa $ scope" - http://onehungrymind.com/angularjs-sticky-notes-pt-1-arch architecture / Một dịch vụ nên được sử dụng để chia sẻ dữ liệu giữa bộ điều khiển thay thế.

(Nếu bạn thực sự muốn chia sẻ dữ liệu thông qua kế thừa phạm vi bộ điều khiển, bạn không cần phải làm gì. Phạm vi con sẽ có quyền truy cập vào tất cả các thuộc tính phạm vi cha. Xem thêm Trình điều khiển tải khác nhau khi tải hoặc điều hướng )

chỉ thị

  1. default ( scope: false) - lệnh không tạo phạm vi mới, do đó không có sự kế thừa ở đây. Điều này dễ, nhưng cũng nguy hiểm vì, ví dụ, một lệnh có thể nghĩ rằng nó đang tạo ra một thuộc tính mới trên phạm vi, trong khi thực tế nó đang ghi đè lên một thuộc tính hiện có. Đây không phải là một lựa chọn tốt để viết các chỉ thị được dự định là các thành phần có thể tái sử dụng.
  2. scope: true- chỉ thị tạo ra một phạm vi con mới kế thừa nguyên mẫu từ phạm vi cha. Nếu có nhiều chỉ thị (trên cùng một phần tử DOM) yêu cầu một phạm vi mới, chỉ có một phạm vi con mới được tạo. Vì chúng ta có sự kế thừa nguyên mẫu "bình thường", điều này giống như ng-include và ng-switch, do đó, hãy cảnh giác với dữ liệu 2 chiều liên kết với các nguyên hàm phạm vi cha và ẩn / che khuất phạm vi con của các thuộc tính phạm vi cha.
  3. scope: { ... }- chỉ thị tạo ra một phạm vi cô lập / cô lập mới. Nó không kế thừa nguyên mẫu. Đây thường là lựa chọn tốt nhất của bạn khi tạo các thành phần có thể sử dụng lại, vì lệnh này không thể vô tình đọc hoặc sửa đổi phạm vi cha. Tuy nhiên, các chỉ thị như vậy thường cần truy cập vào một vài thuộc tính phạm vi cha. Hàm băm đối tượng được sử dụng để thiết lập liên kết hai chiều (sử dụng '=') hoặc liên kết một chiều (sử dụng '@') giữa phạm vi cha và phạm vi cách ly. Ngoài ra còn có '&' để liên kết với các biểu thức phạm vi cha. Vì vậy, tất cả đều tạo các thuộc tính phạm vi cục bộ có nguồn gốc từ phạm vi cha. Lưu ý rằng các thuộc tính được sử dụng để giúp thiết lập liên kết - bạn không thể chỉ tham chiếu tên thuộc tính phạm vi cha trong hàm băm đối tượng, bạn phải sử dụng một thuộc tính. Ví dụ, điều này sẽ không hoạt động nếu bạn muốn liên kết với tài sản mẹparentProptrong phạm vi biệt lập: <div my-directive>scope: { localProp: '@parentProp' }. Một thuộc tính phải được sử dụng để chỉ định từng thuộc tính cha mà chỉ thị muốn liên kết với: <div my-directive the-Parent-Prop=parentProp>scope: { localProp: '@theParentProp' }.
    Cô lập __proto__đối tượng tham chiếu phạm vi . $ Parent của phạm vi cách ly tham chiếu phạm vi cha, vì vậy mặc dù nó bị cô lập và không kế thừa nguyên mẫu từ phạm vi cha, nhưng nó vẫn là phạm vi con.
    Đối với hình ảnh bên dưới chúng tôi có
    <my-directive interpolated="{{parentProp1}}" twowayBinding="parentProp2">
    scope: { interpolatedProp: '@interpolated', twowayBindingProp: '=twowayBinding' }
    Ngoài ra, giả sử lệnh thực hiện điều này trong chức năng liên kết của nó: scope.someIsolateProp = "I'm isolated"
    phạm vi cô lập
    Để biết thêm thông tin về phạm vi cách ly, hãy xem http://onehungrymind.com/angularjs-sticky-notes-pt-2-isreach-scope/
  4. transclude: true- lệnh này tạo ra một phạm vi con "xuyên" mới, được kế thừa nguyên mẫu từ phạm vi cha. Phạm vi xuyên và phạm vi biệt lập (nếu có) là anh em ruột - thuộc tính $ cha của mỗi phạm vi tham chiếu cùng phạm vi cha. Khi cả một phạm vi được bao gồm và một phạm vi cô lập đều tồn tại, cô lập thuộc tính phạm vi $$ nextSibling sẽ tham chiếu phạm vi được nhúng. Tôi không nhận thức được bất kỳ sắc thái nào với phạm vi xuyên.
    Đối với hình dưới đây, giả sử chỉ thị tương tự như trên với phần bổ sung này:transclude: true
    phạm vi xuyên

Đây fiddle có một showScope()chức năng có thể được sử dụng để kiểm tra một cô lập và phạm vi nhúng. Xem hướng dẫn trong các ý kiến ​​trong fiddle.


Tóm lược

Có bốn loại phạm vi:

  1. kế thừa phạm vi nguyên mẫu bình thường - ng-gộp, ng-switch, ng-điều khiển, chỉ thị với scope: true
  2. kế thừa phạm vi nguyên mẫu bình thường với một bản sao / chuyển nhượng - ng-repeat. Mỗi lần lặp lại của ng-repeat tạo ra một phạm vi con mới và phạm vi con mới đó luôn có một thuộc tính mới.
  3. phạm vi cô lập - chỉ thị với scope: {...}. Cái này không phải là nguyên mẫu, nhưng '=', '@' và '&' cung cấp một cơ chế để truy cập các thuộc tính phạm vi cha, thông qua các thuộc tính.
  4. phạm vi xuyên - chỉ thị với transclude: true. Đây cũng là kế thừa phạm vi nguyên mẫu bình thường, nhưng nó cũng là anh em ruột của bất kỳ phạm vi cô lập nào.

Đối với tất cả các phạm vi (nguyên mẫu hoặc không), Angular luôn theo dõi mối quan hệ cha-con (tức là hệ thống phân cấp), thông qua các thuộc tính $ Parent và $$ childHead và $$ childTail.

Sơ đồ được tạo ra với Các tập tin "* .dot", trên github . " Học JavaScript với đồ thị đối tượng " của Tim Caswell là nguồn cảm hứng cho việc sử dụng GraphViz cho các sơ đồ.


48
Bài viết tuyệt vời, quá dài cho một câu trả lời SO, nhưng dù sao cũng rất hữu ích. Vui lòng đặt nó trên blog của bạn trước khi một biên tập viên cắt giảm kích thước.
iwein

43
Tôi đặt một bản sao trên wiki AngularJS .
Mark Rajcok

3
Sửa chữa: "Cô lập __proto__đối tượng tham chiếu phạm vi ." thay vào đó nên là "Cô lập phạm vi __proto__tham chiếu của một đối tượng Phạm vi." Vì vậy, trong hai hình ảnh cuối cùng, các hộp "Đối tượng" màu cam thay vào đó là các hộp "Phạm vi".
Mark Rajcok

15
Asnwer này nên được bao gồm trong hướng dẫn angularjs. Điều này còn hơn thế nữa ...
Marcelo De Zen

2
Wiki khiến tôi hoang mang, đầu tiên nó viết: "Chuỗi nguyên mẫu được tham khảo vì không tìm thấy đối tượng trong ChildScope." và sau đó nó viết: "Nếu chúng ta đặt childScope.propertyX, chuỗi nguyên mẫu không được tham khảo.". Cái thứ hai ngụ ý một điều kiện trong khi cái thứ nhất thì không.
Stephane

140

Tôi không muốn cạnh tranh với câu trả lời của Mark, nhưng chỉ muốn làm nổi bật tác phẩm cuối cùng đã khiến mọi thứ nhấp vào như một người mới đối với thừa kế Javascript và chuỗi nguyên mẫu của nó .

Chỉ có tài sản đọc tìm kiếm chuỗi nguyên mẫu, không viết. Vì vậy, khi bạn thiết lập

myObject.prop = '123';

Nó không tìm kiếm chuỗi, nhưng khi bạn đặt

myObject.myThing.prop = '123';

có một cách đọc tinh tế đang diễn ra trong hoạt động viết đó cố gắng tra cứu myThing trước khi ghi vào chỗ dựa của nó. Vì vậy, đó là lý do tại sao viết thư cho object.property từ đứa trẻ nhận được tại các đối tượng của cha mẹ.


12
Mặc dù đây là một khái niệm rất đơn giản, nhưng nó có thể không rõ ràng lắm vì, tôi tin rằng, rất nhiều người bỏ lỡ nó. Vâng đặt.
moljac024

3
Nhận xét tuyệt vời. Tôi lấy đi, độ phân giải của thuộc tính không đối tượng không liên quan đến việc đọc trong khi độ phân giải của thuộc tính đối tượng thực hiện.
Stephane

1
Tại sao? Động lực cho tài sản viết không đi lên chuỗi nguyên mẫu là gì? Có vẻ điên rồ ...
Jonathan.

1
Sẽ thật tuyệt nếu bạn thêm một ví dụ đơn giản thực sự.
tylik

2
Chú ý rằng nó không tìm kiếm các chuỗi nguyên mẫu cho setters . Nếu không có gì được tìm thấy, nó tạo ra một thuộc tính trên máy thu.
Bergi

21

Tôi muốn thêm một ví dụ về kế thừa nguyên mẫu với javascript vào câu trả lời @Scott Driscoll. Chúng tôi sẽ sử dụng mẫu kế thừa cổ điển với Object.create () là một phần của đặc tả EcmaScript 5.

Đầu tiên chúng ta tạo hàm đối tượng "Parent"

function Parent(){

}

Sau đó thêm một nguyên mẫu vào hàm đối tượng "Parent"

 Parent.prototype = {
 primitive : 1,
 object : {
    one : 1
   }
}

Tạo chức năng đối tượng "Con"

function Child(){

}

Gán nguyên mẫu con (Tạo nguyên mẫu con kế thừa từ nguyên mẫu cha)

Child.prototype = Object.create(Parent.prototype);

Chỉ định hàm tạo nguyên mẫu "Con" thích hợp

Child.prototype.constructor = Child;

Thêm phương thức "changeProps" vào một nguyên mẫu con, nó sẽ viết lại giá trị thuộc tính "nguyên thủy" trong đối tượng Child và thay đổi giá trị "object.one" cả trong đối tượng Child và Parent

Child.prototype.changeProps = function(){
    this.primitive = 2;
    this.object.one = 2;
};

Khởi xướng các đối tượng Cha mẹ (cha) và Con (con trai).

var dad = new Parent();
var son = new Child();

Gọi phương thức thay đổi con (con)

son.changeProps();

Kiểm tra kết quả.

Tài sản nguyên thủy của cha mẹ không thay đổi

console.log(dad.primitive); /* 1 */

Thuộc tính nguyên thủy của con thay đổi (viết lại)

console.log(son.primitive); /* 2 */

Thuộc tính Parent and Child.one đã thay đổi

console.log(dad.object.one); /* 2 */
console.log(son.object.one); /* 2 */

Ví dụ hoạt động tại đây http://jsbin.com/xexurukiso/1/edit/

Thông tin thêm về Object.create tại đây https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/create

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.