2016-12-18 19 views
5

Hãy lấy ví dụ này từ The Good Parts cuốn sách:Khi nào sử dụng 'Array.prototype' và khi nào nên sử dụng 'this' trong JavaScript?

Array.method('unshift', function() { 
    this.splice.apply(this,[0,0].concat(Array.prototype.slice.apply(arguments))); 
    return this; 
}); 

Tại sao tác giả sử dụng this.splice ở một nơi và Array.prototype.slice trong khác?

tôi đã cố gắng trao đổi ra thisArray.prototype với nhau và đã nhận lỗi như sau:

TypeError: Cannot read property 'slice' of undefined

nhưng tôi vẫn không chắc chắn về, làm thế nào để biết khi nào nên sử dụng this hoặc Array.prototype.

+1

Rất liên quan: http: // stackoverflow .com/q/7056925/476 – deceze

+0

Cuốn sách này chưa bao giờ là một cách rất hay để bắt đầu với JavaScript, nhưng giờ đây ** đã quá ** lỗi thời (gần một thập kỷ cũ).Tôi thực sự khuyên bạn nên tìm một cuốn sách tốt hơn để làm việc cùng. –

+0

@torazaburo nhưng tôi đã chọn cuốn sách này, sau khi đọc nó như một cuốn sách được đề nghị từ nhiều nguồn khác nhau. –

Trả lời

8

Trong lần gọi đầu tiên, this đề cập đến mảng mà trên đó unshift được gọi và vì vậy nó được thừa hưởng splice từ Array.prototype.

Trong cuộc gọi thứ hai, tuy nhiên, các mã sử dụng slice vào cái gì đó không phải là một mảng (các arguments pseudo-mảng, mà không có một phương pháp slice). Vì vậy, trong trường hợp đó, Crockford đã truy cập phương thức qua Array.prototype.

Về mặt kỹ thuật, ông có thể đã sử dụng this.slice ở vị trí thứ hai, như thế này:

Array.method('unshift', function() { 
    this.splice.apply(this,[0,0].concat(this.slice.apply(arguments))); 
    return this; 
}); 

... nhưng nó có lẽ sẽ đã gây hiểu lầm, kể từ khi cuộc gọi thứ hai không có gì để làm với các mảng hiện tại tham chiếu bởi this.

+0

@RajatSaxena: Niềm vui của tôi. Tôi đã loại bỏ một cái gì đó gây hiểu lầm ở trên (mã đang sử dụng 'splice' và' slice', nhưng trong câu trả lời ban đầu của tôi, tôi đã nhầm tưởng rằng nó đã sử dụng 'splice' hai lần). –

0

Đôi khi nó là dễ dàng hơn để hình dung mối quan hệ, do đó bạn nhận ra rằng trong nhiều trường hợp chúng ta có foo.bar === Foo.prototype.bar; // true

structure of prototypes

On tạo ra một thể hiện foo, các nguyên mẫu tài sản của các nhà xây dựng Foo được thiết lập như một tham chiếu đặc biệt của foo (__proto__), nếu bạn cố gắng truy cập vào thuộc tính không tồn tại trực tiếp trên foo nơi tiếp theo mà tài sản được tìm kiếm là thông qua tham chiếu đó.

Điều này có nghĩa là khi bạn mong đợi foo chưa được sửa đổi theo cách sẽ ẩn thuộc tính khỏi đối tượng đó, việc bạn cố gắng tra cứu qua foo.bar hoặc Foo.prototype.bar cũng giống như vậy.

Tuy nhiên, như bạn có thể thấy, không phải mọi thứ sẽ có cùng một đường dẫn __proto__, vì vậy bạn không thể giả sử obj.slice sẽ tồn tại, chẳng hạn. Điều này có nghĩa nếu bạn không có một Mảng dụ nhưng bạn muốn lát nó, bạn phải tham khảo lát mặc dù một cách mà bạn biết tồn tại, chẳng hạn như Array.prototype.slice

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