2010-10-19 27 views
22

Douglas Crockford đã viết trong cuốn sách của ông (trang 4):"phương pháp" phương pháp trong cuốn sách Crockford: Javascript: The Good Parts

Trong suốt cuốn sách, một phương pháp method được sử dụng để xác định phương pháp mới, Đây là định nghĩa của nó:

Function.prototype.method = function (name, func) { 
    this.prototype[name] = func; 
    return this; 
}; 

Sau đó, ông bắt đầu sử dụng method này để thêm phương pháp trong Number, String, Function, Object, Array, RegExp, và đây là danh sách đầy đủ:

P33:

Number.method('integer', function() {...}); 
String.method('trim', function() {...}); 

P40 (không chắc chắn nếu có một in lầm trong trang 41: cuối()):

String.method('deentityify', function() {...}()); 

P43 & P44:

Function.method('curry', function() {...}); 

P47 (Tôi nhầm lẫn ở đây, don' t biết tại sao Crockford xác định new phương pháp, và ông dường như không bao giờ sử dụng new phương pháp trong cuốn sách):

Function.method('new', function() {...}); 

P48:

Function.method('inherits', function (Parent) {...}); 

P54:

Object.method('superior', function (name) {...}); 

P62:

Array.method('reduce', function (f, value) {...}); 

P79:

Array.method('pop', function() {...}); 
Array.method('push', function() {...}); 
Array.method('shift', function() {...}); 

P82:

Array.method('splice', function (start, deleteCount) {...}); 

P84:

Function.method('bind', function (that) {...}); 

P88:

RegExp.method('test', function (string) {...}); 
String.method('charAt', function (pos) {...}); 

P90 (không chắc chắn nếu có một in lầm trong trang 91: cuối()):

String.method('entityify', function() {...}()); 

Các Định nghĩa method được dựa trên Function, tại sao nó có thể được sử dụng trong Number, String, Object, Array, RegExp bên cạnh Function? Và có thể sử dụng method này cho các loại dữ liệu khác không?

Một câu hỏi nhỏ khác: trong số64, định nghĩa của Array.dim, Array.matrix, Array.identity không sử dụng ở trên method, tại sao?

Trả lời

20

Tất cả các hàm gốc trong JavaScript được kế thừa từ Function.prototype. Number, String, Object, ArrayRegExp là tất cả các chức năng, do đó chúng được kế thừa từ Function.prototype.

method được dự định sẽ được gọi là chức năng của hàm tạo. Công việc của nó là tạo ra hàm mà bạn cung cấp cho nó thành một phương thức tồn tại cho mọi đối tượng được tạo bởi hàm constructor mà bạn gọi là method. Bạn sẽ nhận thấy rằng trong các hàm mà Crockford chuyển đến method, anh ta sử dụng this, là tham chiếu đến đối tượng mà phương thức được gọi. Array.dim, Array.matrixArray.identity không sử dụng this vì chúng hoạt động độc lập với bất kỳ mảng cụ thể nào và do đó không cần phải là phương pháp của các đối tượng mảng riêng lẻ. Chúng được gán làm các thuộc tính của hàm Array để thuận tiện: chúng có thể tồn tại như nhau một cách bình đẳng như các hàm trong phạm vi toàn cầu.

+0

Tôi không chắc liệu Số, Chuỗi, Đối tượng, Mảng, RegExp (Có thể hàm và ngày và Boolean) là tất cả các chức năng. Có vẻ như họ là Global Objects. – John

+1

@ John: Tôi đảm bảo với bạn, tất cả đều là chức năng. Hãy thử 'alert (typeof Number)' vv nếu bạn không tin tôi, hoặc kiểm tra đặc điểm kỹ thuật (phần 15.1.4): http://www.ecma-international.org/publications/standards/Ecma-262.htm . Họ cũng là tài sản của đối tượng toàn cầu, nếu đó là những gì bạn đang nhận được. –

+1

@ John: Tôi hiểu, bạn đã xem tài liệu của Mozilla tại https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects. Đó là chính xác trong đó cũng như các hàm, 'Số',' Chuỗi', 'Đối tượng' và các đối tượng khác, bởi vì tất cả các hàm đều là các đối tượng; nó cũng đúng là thuộc tính của đối tượng toàn cầu, chúng có sẵn trên toàn cầu để có thể được mô tả là "các đối tượng chung". Tuy nhiên, với sự tồn tại của thuật ngữ được xác định chính thức là "đối tượng toàn cầu", tôi thấy việc Mozilla sử dụng thuật ngữ "Các đối tượng toàn cầu" khá vô ích. –

4

Là một sang một bên, trên P40:

Sự kết thúc() có nghĩa là "sử dụng chức năng rằng chức năng này trở lại", không phải là chức năng bên ngoài trả về nó.

Nếu anh ta đã rời khỏi cuộc thi cuối cùng(), một cuộc gọi để deentityify sẽ trả về một hàm, chứ không phải là một chuỗi.

Nói cách riêng của Douglas Crockford:

Chúng tôi ngay lập tức gọi hàm chúng ta chỉ cần thực hiện với) điều hành (. Lệnh gọi đó tạo ra và trả về hàm trở thành phương thức deentityify.

3

Giải pháp được đưa ra bởi @Tim Down là chính xác, nhưng không hoàn toàn rõ ràng.

đối tượng Function vs Function trường hợp đối tượng

Trước hết, trong javascript, một chức năng cũng là một đối tượng. Từ điều này, tôi có nghĩa là không phải đối tượng được tạo ra bởi new() xây dựng, nhưng bản thân hàm đó. Để tránh nhầm lẫn, tôi sẽ tham chiếu các đối tượng như Đối tượng chức năng và đối tượng được tạo bằng cách sử dụng cấu trúc mới() của hàm là Đối tượng đối tượng hàm.

_ proto _ và các thuộc tính prototype

Bất kỳ đối tượng chức năng trong javascript có hai thuộc tính: _ proto _nguyên mẫu. Hơn nữa, bất kỳ đối tượng đối tượng hàm (được tạo bằng hàm tạo mới) có thuộc tính _ proto _. _ proto _ là những gì định nghĩa thừa kế. Một số nguồn lực tốt về vấn đề này có thể được tìm thấy tại

http://zeekat.nl/articles/constructors-considered-mildly-confusing.html

như thế nào thừa kế được xác định?

Một đối tượng objA thừa hưởng một đối tượng ObjC nếu objA và ObjC được kết nối thông qua bất kỳ số lượng _ proto _. Vì vậy, nếu objA có _ proto _ bằng objB và objB có _ proto _ bằng objC, thì objA kế thừa objB và objC, trong khi objB kế thừa objC.

Điều gì có nghĩa là thừa kế?

Có nghĩa là bất kỳ đối tượng kế thừa nào cũng có thể sử dụng bất kỳ thuộc tính nào của đối tượng được kế thừa.

Function.prototype

là gì Nó là đối tượng mà _ proto _ của mọi đối tượng chức năng đề cập. Điều này có nghĩa là mỗi đối tượng chức năng có quyền truy cập vào các thuộc tính của Function.prototype, vì mỗi đối tượng chức năng đều thừa kế đối tượng Function.prototype. Điều này cũng có nghĩa là nếu thuộc tính được thêm vào đối tượng Function.prototype, nó sẽ có sẵn cho tất cả các đối tượng chức năng có thể trong javascript. Điều này bao gồm Chuỗi, Số, v.v.

this.prototype [name] = func;

này đề cập đến Chức năng đối tượng khi 'phương pháp' được gọi từ đối tượng Chức năng s như Number, String, vv Mà có nghĩa là bây giờ chúng tôi có một tài sản mới trong Chức năng đối tượng với tên "name", và một hàm 'func' của nó.

gì tốt là nguyên mẫu tài sản của đối tượng Chức năng

Một chức năng đối tượng 's nguyên mẫu được gọi bởi các Chức năng đối tượng dụ' s _ proto _ được tạo bằng cách sử dụng cấu trúc mới của hàm đó.

Nếu sau đây được thực hiện:

Number.method ('nguyên', function() {...});

sau đó Number.prototype có phương thức số nguyên được định nghĩa trong đó. Điều này có nghĩa là mỗi đối tượng đối tượng hàm số , ví dụ: Số mới (2.4), sẽ "kế thừa" thuộc tính mới này 'số nguyên' từ Number.prototype, vì đối tượng đối tượng hàm đối tượng sẽ có số _ proto _ được đặt thành Number.prototype.

0

Cố gắng sử dụng phương pháp nguyên mẫu này:

String.prototype.deentityify = function() { ... } 

Sau đó:

document.writeln('<">'.deentityify()); 

Chúng ta có thể thấy: <">

0

Ví dụ: tách lạng bộ có thể được viết lại như sau, nếu có ai đã bị mắc kẹt . Xem jsFiddle demo

Function.prototype.curry = function () { 
var slice = Array.prototype.slice; 
var args = slice.apply(arguments); 
var that = this; 
return function() { 
    return that.apply(null,args.concat (slice.apply(arguments))); 
} 
}; 
var add = function(a, b) 
{ 
    return a + b; 
} 
var add1 = add.curry(1); 
document.writeln(add1(6)); // 7 
Các vấn đề liên quan