2011-11-28 33 views
9

Tôi đang học Javascript, tôi đã sử dụng PHP trong khoảng 10 năm nên tôi có một số kiến ​​thức về Javascript, chủ yếu chỉ cần sử dụng jQuery và hack nó lại với nhau, tôi nghĩ đã đến lúc tôi cố gắng học nó tốt hơn vì vậy tôi đã đọc trên đó.Javascript Chức năng và đối tượng

Dưới đây là ví dụ về cách xác định và gọi một số chức năng của tôi.

Phương pháp 1

function testFunction1() { 
    console.log('TestFunction1() was ran'); 
} 
testFunction1(); 

Phương pháp 2

var testFunction2 = function() { 
    console.log('TestFunction2() was ran'); 
} 
testFunction2(); 

Phương pháp 3

var TestFunction3 = { 
    flag: function() { 
     console.log('TestFunction3.flag() was ran'); 
    }, 
    unflag: function() { 
     console.log('TestFunction3.unflag() was ran'); 
    } 
}; 
TestFunction3.flag(); 
TestFunction3.unflag(); 

Phương pháp 4

var TestFunction4 = { 
    Like: { 
     comment: function() { 
      console.log('TestFunction4.Like.comment() was ran'); 
     }, 
     user: function() { 
      console.log('TestFunction4.Like.user() was ran'); 
     } 
    }, 
    Unlike: { 
     comment: function() { 
      console.log('TestFunction4.Unlike.comment() was ran'); 
     }, 
     user: function() { 
      console.log('TestFunction4.Unlike.user() was ran'); 
     } 
    } 
}; 
TestFunction4.Like.comment(); 
TestFunction4.Like.user(); 
TestFunction4.Unlike.comment(); 
TestFunction4.Unlike.user(); 

Ok vì vậy tôi hiểu phương pháp 1 và 2 được chỉ là một chức năng cuộc gọi cơ bản.

1)
Phương pháp 3 và 4 là câu hỏi bắt đầu, từ bài đăng khác và đọc, tôi không thể coi đây là chức năng cơ bản với không gian tên được áp dụng hay không?

2)
Tôi đã thấy đôi khi một đối tượng sẽ được gọi với từ new tuy nhiên chạy tất cả điều này trong trình duyệt hoạt động tốt nên tôi đoán đây không phải là đối tượng? Nếu nó không phải là một đối tượng, làm thế nào tôi sẽ biến nó thành một đối tượng?

3)
Ví dụ 3 và 4 khá giống với ngoại lệ ví dụ 4 có hàm được xác định 1 cấp sâu hơn ví dụ 3, có tên cho ví dụ 3 và 4 hoặc chúng được coi là giống nhau không?

4)
Cuối cùng trong tất cả 4 ví dụ, có bất kỳ phương pháp nào trong số 4 phương pháp này được ưu tiên hơn phương pháp khác không?

Xin lỗi vì tất cả các câu hỏi trong 1 nhưng tất cả đều có liên quan và tôi không nghĩ rằng tôi cần phải bắt đầu 4 câu hỏi riêng cho việc này.

+0

Bạn có thể hưởng lợi từ việc đọc: http://bonsaiden.github.com/JavaScript-Garden/ và ít nhất là xem lại [tiêu chuẩn ECMAScript] (http: //www.ecma-international.org/publications/standards/Ecma-262.htm). –

+1

Mọi thứ đều là một đối tượng, ngoại trừ 'null' và' undefined'. – zzzzBov

+1

Nếu bạn có thời gian rảnh rỗi hãy xem [The Good Parts] (http://www.amazon.com/exec/obidos/ASIN/0596517742/wrrrldwideweb) của Douglas Crockford. Cuốn sách tương đối ngắn, sau khi đọc nó câu trả lời cho câu hỏi của bạn nên rõ ràng tôi nghĩ. – Jeroen

Trả lời

4

3 là một đối tượng. Nó có các thuộc tính đối tượng, bản thân chúng có các đặc tính là các hàm. 4 là cùng một ý tưởng, chỉ với ít làm tổ.

Theo như sử dụng từ khóa new, đó chỉ là một cách để tạo đối tượng. Khi một hàm được gọi với new, được gọi là gọi hàm tạo. Đó là một trong bốn hàm có thể được gọi. Ba mục còn lại, để hoàn thành, là yêu cầu gọi phương thức , gọi hàmáp dụng lời gọi.

Nếu bạn muốn sử dụng hàm làm hàm tạo, theo quy ước, hãy bắt đầu bằng ký tự viết hoa, sau đó gọi bằng từ khóa new. Điều này tạo ra một đối tượng trống dựa trên Object.prototype và đặt nó bằng this. Khi sử dụng chế độ tạo đối tượng này, bạn sẽ thêm thuộc tính vào đối tượng kết quả bằng cách thêm chúng trực tiếp vào this, tức là this.foo = 12

Phương pháp của đối tượng đó sẽ được thêm vào bằng cách sửa đổi nguyên mẫu của hàm.

YourConstrutor.prototype.newMethod = function() { 
    alert(this.foo); 
}; 

Lưu ý rằng việc sử dụng nhà xây dựng đi kèm với rất nhiều khó khăn, đặc biệt nếu bạn muốn thực hiện thừa kế

Đối tượng có thể được tạo ra một cách đơn giản bằng cách trả lại cho họ từ một chức năng "bình thường":

function createCar() { 
    return { 
     prop1 : 12, 
     someFunc: function() { 
     alert(this.prop1); 
     } 
    } 
} 

Điều này cũng giúp ẩn thông tin dễ dàng:

function createCar() { 
    var protectedInfo = "haha I'm protected"; ///not visible outside this function 
    return { 
     prop1 : 12, 
     showProtectedData: function() { 
     alert(protectedInfo); 
     }, 
     someFunc: function() { 
     alert(this.prop1); 
     } 
    } 
} 

(bạn có thể triển khai thông tin ẩn với các nhà xây dựng, nhưng thông tin được bảo vệ sẽ không hiển thị với các phương pháp bạn đặt trên mẫu thử nghiệm; thông tin được bảo vệ sẽ chỉ được hiển thị với các phương pháp bạn thêm bằng tay để this)

Những bất lợi duy nhất ở đây là sự sáng tạo đó sẽ hơi chậm hơn, vì nó tạo ra mà someFunc phương pháp de novo mỗi lần; với một hàm tạo, nó sẽ tồn tại một lần, như là một phần của nguyên mẫu.

4. Lựa chọn nào thích hợp hơn? Nếu bạn chỉ muốn tạo một đối tượng, sau đó sử dụng 3 hoặc 4. Đơn giản.

Nếu bạn muốn liên tục tạo đối tượng, thì tùy thuộc vào. Bạn sẽ tạo ra hàng chục ngàn vật thể này, sao cho tốc độ đó là quan trọng nhất? Nếu vậy, có thể bạn sẽ muốn một nhà xây dựng. Nếu không, thì nó phụ thuộc vào những gì bạn cảm thấy thoải mái nhất. Tôi tìm thấy một hàm đơn giản trả về một đối tượng rõ ràng nhất và linh hoạt nhất, nhưng đó chỉ là sở thích của tôi. Nhiều nhà phát triển thông minh hơn tôi rất nhiều so với các nhà xây dựng.

1
  1. 3 và 4 vẫn hoạt động, nhưng chúng cũng là đối tượng. 1 và 2 cũng là các đối tượng cũng như các hàm. Tất cả các hàm đều là các đối tượng - JavaScript có các hàm hạng nhất.

  2. Nó khởi tạo một đối tượng. Các chức năng được gọi với newnhà thầu. Họ tạo ra các đối tượng.

  3. Chúng giống nhau. Giống như trong # 1, mức làm tổ không ảnh hưởng đến loại bất kỳ thứ gì ...

  4. Không, bởi vì chúng đều tương đương nhau. A Function là một Object và không quan trọng nó ở đâu. Nói chung, mặc dù, bạn sẽ tránh làm tổ nặng cho mục đích của không gian tên bởi vì nó có thể làm chậm mã của bạn xuống, mà không có tất cả những lợi ích rõ ràng nhiều. JavaScript không thực sự được thiết kế với các không gian tên.

0

AFAIK

1) Trong JS tất cả các chức năng là các đối tượng. Trong trường hợp của 3, có nó sẽ được coi là một đối tượng bởi vì nó bên trong các dấu ngoặc nhọn

3) Chúng giống nhau, nhưng một cách bạn COULD nhạc jazz sẽ trở thành một trong những thuộc tính mức cao nhất và không phải cái khác, mà về cơ bản ẩn chức năng không trả về và cung cấp cho bạn một cách để tạo các phương thức công khai và riêng tư.

4) Có lẽ 4 là gần nhất với những gì tôi nghĩ rằng bạn muốn và sau một số cách tiếp cận hợp lý nhưng như Andrew nói, tôi xin được nghiêng để thay đổi 4 vào một cái gì đó như thế này:

var TestFunction4 = (function(){ 
    return { 
     flag: function() { 
      console.log('TestFunction4.flag() was ran'); 
     }, 
     unflag: function() { 
      console.log('TestFunction4.unflag() was ran'); 
     } 
    } 
})(); 
TestFunction4.flag(); 
TestFunction4.unflag(); 

Note ngoặc tại đuôi của phương pháp này, buộc các chức năng để thực hiện ngay lập tức và làm cho bản thân avaiable trước khi thời gian chạy để phần còn lại của ứng dụng (về tiếng nói, IntelliSense)

EDIT:

Đây là cách tôi muốn sử dụng ' các hàm riêng tư trong phản hồi t o 'lý do tại sao bạn sẽ làm điều này' nhận xét:

var TestFunction4 = (function(){ 
    //private function 
    var private = { 
     aPrivateFunction: function(a) { 
      return a + 1; 
     } 
    } 
    //public return object 
    var public = { 
     flag: function() { 
      console.log('Calling private function aPrivateFunction(10) expecting 11'); 
      console.log('result' + private.aPrivateFunction(10)); 
      console.log('TestFunction4.flag() was ran'); 
     }, 
     unflag: function() { 
      console.log('TestFunction4.unflag() was ran'); 
     } 
    } 
    //return things to expost publicly 
    return public; 
})(); 
+0

Ví dụ 4) của bạn thậm chí không chạy ... và tại sao bạn sẽ làm điều đó? 'function' có thể được ghi đè dễ dàng như các đối tượng có thể. – Ryan

+0

ví dụ trên hoàn toàn là hình minh họa, để chạy nó, bạn cần phải 'trả về' một đối tượng hoặc thuộc tính có chứa chức năng cờ và unflah như tôi đã đề cập trong câu trả lời cho điểm 3, tôi sẽ cập nhật mã để cho bạn biết sẽ chạy nó – dougajmcdonald

+0

Trong câu trả lời cho 'lý do tại sao bạn muốn làm điều đó' đó là một con trỏ trước cho mô đun hóa. Một khi bạn đang trả về một đối tượng của các hàm mà bạn muốn truy cập, bạn có thể định nghĩa các hàm/private 'private' bên trong đối tượng TestFunction4 mà không phải là một phần của đối tượng được trả về. Trong khi TestFunction4 có thể bị ghi đè, các giá trị bên trong không thể AFAIK được truy cập. Tôi sẽ cập nhật lại chức năng này để hiển thị hoạt động này cho một ví dụ bạn có thể chạy. – dougajmcdonald

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