5

Tôi đang cố gắng để có được một đối tượng JavaScript để sử dụng các phép gán "này" của một đối tượng khác, cũng như giả định tất cả nguyên mẫu của đối tượng đó chức năng. Dưới đây là một ví dụ về những gì tôi đang cố gắng để hoàn thành:Chức năng Javascript sử dụng "this =" cho "Phía bên tay trái không hợp lệ trong bài tập"

/* The base - contains assignments to 'this', and prototype functions 
    */ 
function ObjX(a,b) { 
    this.$a = a; 
    this.$b = b; 
} 

ObjX.prototype.getB() { 
    return this.$b; 
} 

function ObjY(a,b,c) { 
    // here's what I'm thinking should work: 
    this = ObjX(a, b * 12); 
    /* and by 'work' I mean ObjY should have the following properties: 
    * ObjY.$a == a, ObjY.$b == b * 12, 
    * and ObjY.getB == ObjX.prototype.getB 
    * ... unfortunately I get the error: 
    *  Uncaught ReferenceError: Invalid left-hand side in assignment 
    */ 

    this.$c = c; // just to further distinguish ObjY from ObjX. 
} 

Tôi muốn được biết ơn đối với những suy nghĩ của bạn về làm thế nào để có ObjY bao hàm tập ObjX để 'này' (tức là không phải lặp lại tất cả các this.$* = * bài tập trong ObjY's constructor) và có ObjY giả sử ObjX.prototype.

Suy nghĩ đầu tiên của tôi là để thử như sau:

function ObjY(a,b,c) { 
    this.prototype = new ObjX(a,b*12); 
} 

Lý tưởng nhất là tôi muốn tìm hiểu làm thế nào để thực hiện điều này một cách nguyên chủng (tức là không phải sử dụng bất kỳ của những sản phẩm thay thế OOP 'cổ điển' như Base2).

Có thể cần lưu ý rằng ObjY sẽ ẩn danh (ví dụ: factory['ObjX'] = function(a,b,c) { this = ObjX(a,b*12); ... }) - nếu tôi có thuật ngữ đúng.

Cảm ơn bạn.

+1

liên quan: [? Tại sao tôi không thể gán một giá trị mới cho “này” trong một hàm nguyên mẫu] (http: // stackoverflow.com/q/9713323/1048572) – Bergi

Trả lời

15

Bạn thực sự không thể làm điều đó, bởi vì giá trị this theo định nghĩa là không thay đổi, bạn không thể thay đổi theo cách mà nó tham chiếu đến.

Một cách giải quyết sẽ được sử dụng call hoặc apply phương pháp để chạy chức năng ObjX constructor của bạn trong đối tượng this của ObjY:

function ObjY(a,b,c) { 
    ObjX.call(this, a, b * 12); 
    this.$c = c; 
} 

Trong ví dụ trên, hàm ObjX được thực hiện thay đổi giá trị this của nó, vì vậy tất cả các tiện ích mở rộng thuộc tính bạn thực hiện cho đối tượng đó trong hàm này, sẽ được phản ánh trong đối tượng mới mà giá trị this đề cập đến hàm tạo ObjY.

Khi phương pháp call kết thúc, đối tượng this sẽ được tăng cường và bạn có thể tạo thêm tiện ích mở rộng thuộc tính, như thêm giá trị $c.

Edit: Về nguyên mẫu, mẫu của bạn sẽ không hoạt động, vì prototype tài sản không có ý nghĩa đặc biệt đối với đối tượng trong lập trường nó sẽ giống như bất kỳ tài sản khác, nó phải được sử dụng trên chức năng constructor.

Tôi nghĩ rằng bạn có thể nhầm lẫn thuộc tính prototype của các nhà thầu với thuộc tính nội bộ [[Prototype]] mà tất cả các đối tượng đều có.

Thuộc tính [[Prototype]] chỉ có thể được thiết lập bởi các new điều hành (thông qua các hoạt động nội bộ [[Construct]]), khách sạn này không thể thay đổi, (mặc dù một số hiện thực, giống như một Mozilla, bạn có thể truy cập nó thông qua obj.__proto__;, và trong ECMAScript 5, phương pháp Object.getPrototypeOf đã được giới thiệu, nhưng tôi sẽ không khuyên bạn nên gây rối trực tiếp với nó).

Thực ra, khi hàm khởi tạo của bạn được thực hiện, thuộc tính nội bộ [[Prototype]] của đối tượng mà giá trị tham chiếu this đề cập, đã được đặt thành thuộc tính prototype của hàm tạo.

Vì vậy, như @Anurag ý kiến, bạn có thể thiết lập các ObjY.prototype đến một mới được tạo ra ObjX đối tượng:

function ObjY(a,b,c) { 
    ObjX.call(this, a, b * 12); 
    this.$c = c; 
} 

ObjY.prototype = new ObjX(); 
ObjY.prototype.constructor = ObjY; 

Điều đó sẽ làm cho điều đó ObjY kế thừa của bạn cũng thuộc tính thêm vào ObjX.prototype, và như bạn thấy, Tôi đã thay đổi ObjY.prototype.constructor, vì việc gán trong dòng ở trên sẽ làm cho thuộc tính này trỏ sai đến ObjX.

bài được khuyến nghị:

+1

Cảm ơn CMS. Great liên kết, quá. Câu hỏi khác là làm thế nào để gán các nguyên mẫu - có thể được thực hiện từ bên trong hàm tạo không? –

+0

@Brian, bạn được chào đón, vâng tôi có lỗi đánh máy! – CMS

+0

@Brian, đặt một đối tượng của ObjX làm nguyên mẫu cho ObjY, để có được các phương pháp của nó quá. 'ObjY.prototype = new ObjX;'. Phương thức và thuộc tính nếu không tìm thấy trong đối tượng hiện tại, được tra cứu trong chuỗi nguyên mẫu. – Anurag

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