2012-11-19 19 views
6

Ok I nên biết câu trả lời cho điều này nhưng vì một lý do nào đó mà tôi chưa bao giờ thực sự hiểu hoặc có nhu cầu thực sự biết JavaScript.JavaScript cơ bản OO

Câu hỏi của tôi là: Nhìn vào các mẫu mã bên dưới, tôi hiểu chính xác hay tôi thiếu một số thông tin.


Mẫu 1

Cần phải nhanh chóng các chức năng (hoặc lớp) để sử dụng phương pháp IsOld, và một bản sao riêng của IsOld chức năng sẽ được tạo ra cho mỗi trường hợp.

function MyClass1() { 
    this.IsOld = function (age) { 
     if (age > 40) { 
      return true; 
     } 
     return false; 
    }; 
} 

// sample usage 
var m1 = new MyClass1(); 
console.log(m1.IsOld(34)); 

Mẫu 2

Cần phải nhanh chóng nhưng không giống như MyClass1 các đoạn mã script sẽ không cần phải tạo ra một bản sao của phương pháp IsOld cho mỗi trường hợp lớp.

var MyClass2 = (function() { 
    function MyClass2() { } 

    MyClass2.prototype.IsOld = function (age) { 
     if (age > 40) { 
      return true; 
     } 
     return false; 
    }; 

    return MyClass2; 
})(); 

// sample usage 
var m2 = new MyClass2(); 
console.log(m2.IsOld(34)); 

Mẫu 3

Không cần phải nhanh chóng các chức năng/lớp để truy cập phương pháp IsOld. Một ví dụ đơn lẻ của phương thức IsOld được sử dụng trên tất cả các lời gọi.

var MyClass3 = { 
    IsOld: function (age) { 
     if (age > 40) { 
      return true; 
     } 
     return false; 
    }, 
}; 

// sample uage 
console.log(MyClass3.IsOld(34)); 

Lưu ý: Tôi đoán có rất nhiều câu hỏi/câu trả lời tương tự ở đây trên SO nhưng vì một lý do nào đó tôi không thể tìm thấy câu hỏi thực sự có ý nghĩa đối với tôi.

+1

của bạn sự hiểu biết là chính xác, mặc dù ví dụ thứ hai là phức tạp không cần thiết với biểu thức hàm IMO ngay lập tức. –

+0

@ FelixKling: Thực ra đây là cách CoffeeScript biên dịch các lớp của nó: http://coffeescript.org/#try:class%20Auto – Amberlamps

Trả lời

2

Sự hiểu biết của bạn có vẻ đúng.

Nếu bằng "cần khởi tạo", bạn có nghĩa là sử dụng từ khóa 'mới', tôi muốn thêm nội dung nào đó vào đây.

Trong việc sử dụng JavaScript của từ khóa mới không phải là cách duy nhất để tạo các phiên bản mới. (Đã chỉnh sửa theo nhận xét) Và bất kỳ chức năng nào cũng có thể hoạt động như một hàm khởi tạo.

Khi bạn sử dụng từ khoá 'mới' tiếp theo bất kỳ chức năng (nói 'x') những gì nó làm là

  1. Tạo đối tượng mới (nói 'y'), và thiết lập nguyên mẫu chức năng x như mới đối tượng (y's) prototype.
  2. Gọi hàm 'x' trong ngữ cảnh y của đối tượng mới tạo, tức là điều này sẽ ám chỉ đối tượng mới 'y' bên trong hàm 'x'
  3. Nếu hàm không trả về đối tượng, trả về đối tượng mới 'x' được tạo bởi toán tử mới là kết quả của biểu thức mới.

Đây là một nguồn tốt cho bạn để tìm hiểu JavaScript bằng cách Douglas Crockford (http://javascript.crockford.com/)

Vì vậy, nếu bạn lo lắng về bộ nhớ (bạn nên có), sử dụng một hàm constructor, và thêm tất cả các các phương thức phổ biến để thực hiện nguyên mẫu như bạn đã làm trong Ví dụ 2.

Sau đó tất cả các phương thức đó sẽ được kế thừa cho tất cả các đối tượng được tạo bằng cách sử dụng hàm này làm hàm tạo. Tuy nhiên, như đã đề cập trước khi tôi nghĩ rằng mẫu 2 có thể được đơn giản:

var MyClass2 = function MyClass2() { }; 

MyClass2.prototype.IsOld = function (age) { 
    if (age > 40) { 
     return true; 
    } 
    return false; 
}; 

var obj = new MyClass2(); 
+1

Từ khóa mới không bắt buộc đối với các trường hợp được sử dụng ở đây. – nnnnnn

+0

Có, tôi đồng ý, vì các chức năng này không tạo đối tượng bên trong chúng. Những gì tôi có nghĩa là để nói là sử dụng 'mới' là không bắt buộc để tạo ra các đối tượng mới. – BuddhiP

1

Theo như tôi biết, bạn đúng trong cả 3 trường hợp.

  1. Không cần khởi tạo IsOld và cho mọi trường hợp sẽ có chức năng mới được tạo.
  2. Không cần phải tạo nhanh IsOld vì nguyên mẫu.
  3. Không cần khởi tạo IsOld vì MyClass3 đã là một cá thể (đối tượng không phải là hàm).
1

Dường như với tôi có được một số hiểu lầm liên quan đến cấu trúc của các lớp và bản chất năng động của Javascript: cho tất cả các trường hợp được trình bày, mỗi trường hợp của "class" tạo ra một hàm mới chưa được đặt tên.

Nếu bạn muốn khai báo "lớp học" theo một cách truyền thống hơn (như C++ hay Java), bạn nên:

1) Xác định các chức năng:

function MyClass_IsOld(age) { 
    return (age > 40); 
} 

2) Tạo "class" và xác định nguyên mẫu của nó:

function MyClass() { /* put any instance constructor logic here */ }; 
MyClass.prototype.IsOld = MyClass_IsOld; 

3) Sử dụng các lớp:

var myInstance = new MyClass(); 
console.log(myInstance.IsOld(37)); 

Nếu bạn muốn sử dụng "phương pháp" như một chức năng thường xuyên, tuyên bố nó trên toàn cầu, như:

function MyClass_IsOld(age) { 
    return (age > 40); 
} 
function MyClass() { /* put any instance constructor logic here */ }; 
MyClass.prototype.IsOld = MyClass_IsOld; 

var myInstance = new MyClass(); 
console.log(myInstance.IsOld(37));  // use as a method 
console.log(MyClass_IsOld(37));   // use as a function 

Nếu bạn muốn ẩn các chi tiết thực hiện, tạo ra một đóng cửa:

var MyClass = (function() { 
    function _MyClass_IsOld(age) { 
     return (age > 40); 
    } 
    function _MyClass() { /* put any instance constructor logic here */ }; 
    _MyClass.prototype.IsOld = _MyClass_IsOld; // use as a method 

    return _MyClass; 
})(); 

var myInstance = new MyClass(); 
console.log(myInstance.IsOld(37));  // use as a method 
console.log(MyClass_IsOld(37));   // ERROR: undefined function 
+0

_ "trong ví dụ thứ hai, nhân tiện, nguyên mẫu được ghi đè cho mỗi trường hợp được tạo ra." _ - Không, nó được tạo một lần trong biểu thức hàm được gọi ngay lập tức trả về hàm tạo 'MyClass2()'. Có một cái nhìn khác ... – nnnnnn

+0

Vâng, bạn đã đúng, @nnnnnn, tôi đã bỏ qua các nhà xây dựng lớp và nhầm lẫn bản thân mình với các nhà xây dựng trường hợp. Đây là, bằng cách này, làm thế nào tôi sử dụng để thực hiện các lớp học trên Javascript. Cảm ơn bạn đã "lên đầu". –

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