2012-08-16 27 views
7

Tôi là nhà phát triển cấp trung bình javascript đang cố gắng hiểu cách thư viện xương sống hoạt động nội bộ và sẽ đánh giá cao nếu ai đó giúp tôi giải quyết một số thách thức.giải thích đối tượng xương sống và mô hình tạo lớp

vì vậy đây là những gì tôi hiểu

định nghĩa cơ bản của hàm xây dựng trong Backbone được

Backbone.Model = function(attributes, options) { } 

sau đó họ sử dụng mục đích chung mở rộng phương pháp để thêm các tính năng phổ biến trong các mẫu nhà xây dựng của chúng tôi.

_.extend(Backbone.Model.prototype, Backbone.Events, {...}) 

nay đến phần này tôi biết chính xác những gì đang xảy ra và sẽ được hạnh phúc để nhanh chóng đối tượng mới dù đoạn mã sau

var user = new Backbone.Model() 

và đây là phần tôi đang tìm kiếm thử thách

ofcourse nó không phải là cách chúng tôi instantiate một đối tượng trong Backbone nhưng chúng tôi sử dụng mở rộng phương pháp

var Users = Backbone.Model.extend({}); 
var user = new Users() 

và trong mã xương sống

Backbone.Model.extend = extend; 

var extend = function(protoProps, classProps) { 
     var child = inherits(this, protoProps, classProps); 
     child.extend = this.extend; 
     return child; 
}; 

var inherits = function(parent, protoProps, staticProps) { 
    var child; 
    if (protoProps && protoProps.hasOwnProperty('constructor')) { 
     child = protoProps.constructor; 
    } else { 
     child = function() { 
      return parent.apply(this, arguments); 
     }; 
    } 
    _.extend(child, parent); 
    ctor.prototype = parent.prototype; 
    child.prototype = new ctor(); 
    if (protoProps) _.extend(child.prototype, protoProps); 
    if (staticProps) _.extend(child, staticProps); 
    child.prototype.constructor = child; 
    child.__super__ = parent.prototype; 
    return child; 
}; 

xin vui lòng giải thích cho tôi những gì đang xảy ra bên trong thừa kế chức năng và những gì là lợi ích của mở rộng cách tiếp cận phương pháp

+0

Backbone có nguồn với ý kiến: http://documentcloud.github.com/backbone/docs/backbone.html Tìm kiếm phương pháp kế thừa. Họ có một mô tả tốt đẹp. – jForrest

Trả lời

10

extend chức năng gạch dưới của kết hợp các thành viên (các chức năng và tài sản) từ thứ hai đối số vào đầu tiên. Ví dụ:

var reciever = { 
    name: "Jonny", 
    age: 29 
}; 

var supplier: { 
    languages: [ "javascript", "actionscript" ]; 
    sayHi: function() { 
     console.log("Hi, name name is " + this.name); 
    } 
}; 

_.extend(receiver, supplier); 

Sau khi thực hiện đoạn mã trên, các đối tượng tiếp nhận sẽ được tăng cường (sửa đổi) và bây giờ trông như thế này:

/* 
    { 
     age: 29, 
     languages: [ "javascript", "actionscript" ], 
     name: "Jonny", 
     sayHi: <<function>> 
    } 
*/ 
console.dir(receiver); 

Lưu ý rằng đối tượng nhà cung cấp vẫn chưa sửa đổi và đối tượng nhận đạt được tất cả các thuộc tính và chức năng từ nhà cung cấp. Quy trình này thường được gọi là mixin và được sử dụng để tránh phải thực hiện lại các chức năng (như là một phần của nguyên tắc lập trình rộng hơn biết một số DRY - Don't Repeat Yourself).

Bây giờ với chức năng factory method để trả lại cho bạn một hàm xây dựng có thể được sử dụng để tạo các phiên bản mới của mô hình với chức năng nội bộ inherits. Hàm inherits lấy khái niệm mixin thêm một bước tạo một inheritance chain giữa đối tượng được cung cấp và một phụ huynh (trong trường hợp cụ thể này, đối tượng Backbone.Model).

var child; 
if (protoProps && protoProps.hasOwnProperty('constructor')) { 
    child = protoProps.constructor; 
} else { 
    child = function() { 
     return parent.apply(this, arguments); 
    }; 
} 

Khối mã đầu tiên này đang cố gắng tìm hàm hàm dựng bên trong băm đối tượng được cung cấp; nếu không có thì nó sẽ tạo ra một hàm Constructor mới cho bạn, nó tự động chuyển các đối số đã cung cấp tới số của riêng mình thay thế.

_.extend(child, parent); 

Tiếp theo chúng tôi gọi phương thức mở rộng của gạch dưới để trộn tất cả các thuộc tính và hàm vào hàm tạo hàm; điều này đảm bảo rằng mỗi cá thể bạn tạo có dữ liệu riêng của nó (ví dụ: thuộc tính không tĩnh và được chia sẻ trên tất cả các phiên bản mà bạn tạo).

ctor.prototype = parent.prototype; 
child.prototype = new ctor(); 
if (protoProps) _.extend(child.prototype, protoProps); 
if (staticProps) _.extend(child, staticProps); 
child.prototype.constructor = child; 
child.__super__ = parent.prototype; 

Khối cuối cùng này là thú vị nhất và tạo mối quan hệ giữa nguyên mẫu của hàm tạo mới được tạo và nguyên mẫu đối tượng của cha mẹ (Backbone.Model). Bằng cách này, tất cả các cá thể mới được trả về bởi Constructor sẽ chứa các phương thức mô hình xương sống thông thường (ví dụ: getset) khi chúng được giải quyết từ chuỗi nguyên mẫu. Nếu bạn muốn tìm hiểu thêm về khối mã cụ thể này, Douglas Crockford's article on Prototypal inheritance là một nơi tuyệt vời để bắt đầu.

Mấu chốt của phương pháp này là nó cho phép bạn cung cấp một hash của các thuộc tính và chức năng mà kết quả chức năng Constructor sẽ sử dụng như một kế hoạch chi tiết, ví dụ:

var Person = Backbone.Model.extend({ 
    name: "Jon Doe", 
    sayHi: function() { 
     console.log("Hi, my name is " + this.get("name")); 
    } 
}); 

Bây giờ mỗi đối tượng Person bạn nhanh chóng sẽ có cả một name bất động sản và một sayHi chức năng, ví dụ:

var dave = new Person(); 
dave.sayHi(); // "Hi, my name is Jon Doe" 

dave.set("name", "Dave"); 
dave.sayHi(); // "Hi, my name is Dave" 

// You can also supply properties when invoking the constructor. 
var jimmy = new Person({ name: "Jimmy" }); 
jimmy.sayHi(); // "Hi, my name is Jimmy" 
+0

cảm ơn lời giải thích tuyệt vời, mặc dù tôi vẫn còn khá bối rối với khối mã này 'if (protoProps && protoProps.hasOwnProperty ('constructor')) { child = protoProps.constructor; } ' không phải lúc nào cũng là đối tượng và điểm của việc sử dụng nó là gì. 'else { child = function() { trả về parent.apply (điều này, đối số); }; } ' và khối mã này là giống như trở về Backbone.Model (cha mẹ, protoProps, staticProps) mà là một lần nữa bối rối như đối tượng tranh luận sẽ có tham số cha mẹ whats hại trong việc sử dụng chỉ 'con = function() {} ' –

+0

Nếu xương sống được xác định sẽ sử dụng hàm khởi tạo của bạn. nếu không nó sẽ sử dụng hàm tạo mô hình của Backbone. constructor này cũng cần phải biết các đối số passt cho đối tượng. do đó bạn cần gọi hàm tạo cha mẹ với phương thức parent.apply. –

Các vấn đề liên quan