2012-01-11 42 views
5

Tôi đang cố gắng tối đa hóa việc sử dụng lại một số mã. Mở tùy chỉnh của tôi đối tượng javascript (Tôi sẽ sử dụng PhoneNumber làm ví dụ vì lợi ích của sự đơn giản), tôi đang thiết lập một chức năng nguyên mẫu như thế này:Đối tượng tùy chỉnh Javascript là Generic

var Map = { 
    write: function() { 
     alert('My object is ' +this); 
    } 
}; 

function PhoneNumber(number) { 
    this.number = number; 
} 

PhoneNumber.prototype = Map; 

//I can call the write function like so 
var phoneObject = new PhoneNumber('1234567894'); 
phoneObject.write(); //ALERT My Object is Object{number:'1234567894'} 

Tất cả mọi thứ hoạt động tốt, ngoại trừ một thực tế rằng đối với một số lý do nó quay đối tượng Số điện thoại của tôi thành một đối tượng chung thay vì giữ hàm tạo PhoneNumber của nó. Nếu tôi thực sự đặt chức năng ghi bên trong các nguyên mẫu đối tượng như thế này, nó hoạt động hoàn hảo.

function PhoneNumber(number) { 
    this.number = number; 
} 

PhoneNumber.prototype.write = function() { 
    alert('My object is ' +this); 
} 

var phoneObject = new PhoneNumber('1234567894'); 
phoneObject.write(); //ALERT My object is PhoneNumber{number:'1234567894'} 

Nhưng tôi thực sự không phải làm theo cách này vì nhiều đối tượng sử dụng chức năng ghi và tất cả đều thực hiện theo cùng một cách chính xác. Làm thế nào tôi có thể tránh các đối tượng của tôi chuyển đổi mình thành các nhà xây dựng chung? Rõ ràng tôi đang thiết lập đối tượng Map trên nguyên mẫu một cách sai, nhưng nó khá quan trọng là tôi không phải sao chép mã trực tiếp từ Map vào hàm nguyên mẫu đối tượng. Bất kỳ ý tưởng?

+0

Điều này chứng tỏ tại sao toàn bộ 'new'/'.constructor' /' điều .prototype' là một mớ hỗn độn lớn và một đường cú pháp thực sự bị rò rỉ cho cơ chế nguyên mẫu thừa kế tao nhã bên dưới, và 'Object.create' là con đường thực sự. QED :) – Kos

Trả lời

2

Bạn quên thiết lập PhoneNumber.prototype.constructor

Khi bạn làm PhoneNumber.prototype = Map bạn phá hủy tài sản constructor

PhoneNumber.prototype = Map; 
PhoneNumber.prototype.constructor = PhoneNumber; 

Tất nhiên điều đó sẽ không làm việc vì bạn chỉ làm Map.constructor = PhoneNumber mà phá vỡ nếu bạn sử dụng Map như nhiều mẫu . Vì vậy, bạn chỉ nên có PhoneNumber kế thừa từ bản đồ

PhoneNumber.prototype = Object.create(Map, { 
    constructor: { value: PhoneNumber } 
}); 
+0

Object.create() có phải là giải pháp trình duyệt chéo không? Tôi gặp một chút rắc rối khi hiểu nó hoạt động như thế nào? – ryandlf

+0

@ryandlf [Object.create] (https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/create) trình duyệt chéo -> có, trình duyệt cũ -> không. – Raynos

+0

Tại sao nó là một lựa chọn tốt hơn để sử dụng phương pháp Object.create của bạn trái ngược với cách Umesh đang làm điều đó trong một câu trả lời khác? Tôi chỉ tò mò và cố hiểu toàn bộ điều Object.create. Dường như với tôi rằng Object.create được sử dụng nhiều hơn hoặc ít hơn để thay thế từ khóa "mới" khi tạo các đối tượng mới, không thêm các hàm vào một mẫu thử nghiệm hiện có. Với phương pháp của bạn, tôi vẫn có thể gọi phoneObj.write()? – ryandlf

0

Tôi nhận được My object is [object Object] với cả hai phiên bản trong Firefox.

Bạn có thể muốn xem xét bài cũ này:

How do I get the name of an object's type in JavaScript?

cách cụ thể, phần về các nhà xây dựng và kiểm tra các loại đối tượng sử dụng instanceof. Hãy nhớ rằng không có thứ gì như một lớp trong JavaScript, vì vậy khi bạn khởi tạo một đối tượng, nó thực sự không có ý nghĩa của 'type', và những thứ như instanceof là loại hacks để giải quyết vấn đề này.

+0

Nhận đối tượng của tôi là đối tượng là những gì tôi không muốn. Nó phải là PhoneNumber (hoặc bất kỳ hàm tạo nào mà tôi đang sử dụng). Tôi biết làm thế nào để có được tên constructor, đó là vấn đề là tôi không thể có được constructor thực tế vì vì một số lý do nó chuyển đổi nó thành một đối tượng chung. – ryandlf

-1

Dường như đối tượng được trả về là PhoneNumber mà không cần phương thức toString. Hãy thử điều này:

var Map = { 
    write: function() { 
     alert('My object is ' +this); 
    } 
}; 

function PhoneNumber(number) { 
    this.number = number; 
    this.toString = function(){return "PhoneNumber"} 
} 

PhoneNumber.prototype = Map; 

//I can call the write function like so 
var phoneObject = new PhoneNumber('1234567894'); 
phoneObject.write(); //ALERT My Object is Object{number:'1234567894'} 
+0

Vui lòng cung cấp thông tin cho hạ cấp. :) –

0
function PhoneNumber(number) { 
    this.number = number; 
} 
var Map={ 
    write:function(){   
     console.log('My object is ' +this.number); 
    } 
} 
PhoneNumber.prototype.write = Map.write; 

var phoneObject = new PhoneNumber(1234567894); 
phoneObject.write(); 

hoạt động tại đây. nhưng ở đây, Bằng bất cứ cách nào bạn cần phải nói cho đối tượng Map rằng Object có số là biến của nó.

+0

Điều này không hoạt động. – ryandlf

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