2012-04-13 13 views
9

Tôi đã đọc lên trên shim Crockford để ngăn chặn việc ghi đè các nguyên mẫu, và hiểu rằng nó không phải là giải pháp cuối cùng tất cả/tất cả mọi lúc. Tôi cũng hiểu rằng ES5 Shim có thể là một giải pháp thay thế khả thi cho điều này. Tôi cũng đọc this post which provides a more robust, secure alternative.Hiểu về Crockford's Object.create shim

Tuy nhiên, tôi muốn biết shim Object.create của anh ấy là "nói" và sau đó "đang thực hiện". Ai đó có thể vui lòng cho tôi biết nếu nhận xét giải thích của tôi đúng không?

if (typeof Object.create === 'undefined') { 
//If the browser doesn't support Object.create 

    Object.create = function (o) { 
    //Object.create equals an anonymous function that accepts one parameter, 'o'. 

    function F() {}; 
    //Create a new function called 'F' which is just an empty object. 

    F.prototype = o; 
    //the prototype of the 'F' function should point to the 
    //parameter of the anonymous function. 

    return new F(); 
    //create a new constructor function based off of the 'F' function. 
    }; 
} 

//Then, based off of the 'Lost' example in the Crockford book... 

var another_stooge = Object.create(stooge); 

//'another_stooge' prototypes off of 'stooge' using new school Object.create. 
//But if the browser doesn't support Object.create, 
//'another_stooge' prototypes off of 'stooge' using the old school method. 

Bằng cách này, nguyên mẫu của đối tượng 'stooge' không thể ghi đè khi chúng tôi bổ sung nội dung vào 'another_stooge'. Không cần phải thiết lập lại nguyên mẫu 'stooge' bằng cách sử dụng 'hàm tạo'.

Cảm ơn trước,

-k

Trả lời

14
if (typeof Object.create !== 'function') { 
    Object.create = function (o) { 
     function F() {} 
     F.prototype = o; 
     return new F(); 
    }; 
} 
var oldObject={prop:'Property_one' }; // An object 
var newObject = Object.create(oldObject); // Another object 

Trong ví dụ trên chúng tôi đã tạo một đối tượng mới sử dụng newObjectcreate phương pháp mà là một chức năng thành viên của Object đối tượng mà chúng tôi đã thêm trong đối tượng Object trước đó trong ví dụ của chúng tôi (Crockford). Về cơ bản, phương pháp create khai báo hàm F, một đối tượng rỗng every function is a first class object in javascript và sau đó chúng tôi đã thừa kế nguyên mẫu o (trong trường hợp đó o cũng là đối tượng oldObject được truyền làm tham số của phương thức tạo) chúng tôi đã trả về đối tượng mới (một thể hiện của F) bằng cách sử dụng return new F(); đến biến số newObject, vì vậy bây giờ newObject là một đối tượng kế thừa số oldObject. Bây giờ nếu bạn viết console.log(newObject.prop); thì nó sẽ xuất ra Property_one vì đối tượng newObject của chúng tôi đã kế thừa số oldObject và đó là lý do tại sao chúng tôi có giá trị là propProperty_one. điều này được gọi là thừa kế nguyên mẫu.

Bạn phải vượt qua một đối tượng như tham số của phương pháp create

+0

A-ha! Tôi nghĩ rằng tôi đã nhận nó. Cảm ơn Sheikh ... giúp đỡ của bạn được đánh giá cao !!! – kaidez

+0

Bạn đang chào đón nhiều nhất :-) –

0

Tất cả nó làm là tạo một constructor đối tượng mới, đó là F, nó sau đó gán các đối tượng thông qua đối với tài sản nhà xây dựng nguyên mẫu để đối tượng mới tạo ra với Hàm tạo F thừa hưởng các phương thức đó.

Sau đó nó sử dụng các nhà xây dựng để trả lại một đối tượng mới được khởi tạo (mới F() => F.prototype)

Nhưng một Crockford thất bại trong việc phân công lại các nhà xây dựng đúng như bình thường các nhà xây dựng đối tượng mới nên giống nhau là hàm tạo đối tượng mà nó kế thừa từ đó.

+0

Xin chào gillesc. Cảm ơn vì đã phản hồi! Vì vậy, khi điều này được sử dụng, điều đó có nghĩa là nguyên mẫu của cấu trúc cần phải được đặt lại? Một cái gì đó như: stooge.prototype.constructor = stooge; Cảm ơn bạn một lần nữa! – kaidez

0

On bình luận của bạn:

> //Object.create equals an anonymous function that accepts one parameter, 'o'. 

Tốt hơn để nói rằng một chức năng được gán cho create tài sản của Object. Tất cả các chức năng có thể được coi là vô danh, chỉ một số chức năng được gán cho các thuộc tính hoặc biến được đặt tên, những người khác thì không.

> //Create a new function called 'F' which is just an empty object. 

Khai báo chức năng. Vâng, đó cũng là một đối tượng.

>  F.prototype = o; 
>  //the prototype of the 'F' function should point to the 
>  //parameter of the anonymous function. 

Tham chiếu đến o được gán cho F.prototype viết ngắn hơn một chút.

>  //create a new constructor function based off of the 'F' function. 

Không, phải là "Trả về phiên bản F". Vì vậy đối tượng trả về có một nội bộ [[Prototype]] tham chiếu đối tượng được truyền cho hàm. Phần lộn xộn là hàm F vô dụng phải được tạo ra để thực hiện thủ thuật, và hàm tạo của đối tượng được trả về sẽ không có giá trị hữu ích vì nó tham chiếu đến F rỗng.

Không phải là thuộc tính hàm tạo là rất đáng tin cậy hoặc đặc biệt hữu ích bình thường.

Bằng cách này, nguyên mẫu của đối tượng 'stooge' không thể bị ghi đè khi chúng tôi bổ sung nội dung vào 'another_stooge'. Không cần phải đặt lại nguyên mẫu 'stooge' 'sử dụng' hàm tạo '.

Đó là một tuyên bố lạ. * another_stooge * có stooge vì nó là riêng tư [[Prototype]], nó không được kế thừa từ stooge.prototype nhưng từ stooge.[[Prototype]].

Nếu bạn muốn another_stooge để kế thừa từ stooge.prototype, hãy sử dụng Object.create(stooge.prototype) hoặc Object.create(new stooge()), trước đây có thể phù hợp hơn.

Tôi hy vọng rằng tất cả đều có ý nghĩa.

+0

Xin chào RobG. Cảm ơn vì đã phản hồi! Tôi phải đọc lại cú pháp đầy đủ nhưng tôi chắc chắn biết nhiều hơn tôi đã làm một giờ trước. Cảm ơn một lần nữa! – kaidez

0

Có hai thủ thuật ở đây:

  1. F không phải là một chức năng đơn giản, đó là một nhà xây dựng.
  2. "F.prototype" chỉ là một tài sản, nó không có gì với thừa kế trong thời điểm này. Bí quyết thực sự là khi chúng ta sử dụng "new F()", "new" tạo một đối tượng mới, gọi hàm khởi tạo (không làm gì ở đây) VÀ thiết lập trường "prototype" bên trong của đối tượng mới với giá trị "F.prototype", vì vậy đối tượng trả về sẽ kế thừa từ "o".

Vì vậy, tôi nghĩ, đó là:

  • F là một constructor
  • F không được kế thừa từ o
  • "F mới" (đó là đối tượng trả lại) được kế thừa từ o
-1

Tôi đoán đặt tên hàm nội bộ là Object thay vì F làm cho đối tượng kết quả trông gần hơn với những gì Object.create() w ould tạo ra.

if (typeof Object.create !== 'function') { 
    Object.create = function (o) { 
     function Object() {} 
     Object.prototype = o; 
     return new Object(); 
    }; 
}