2012-06-25 26 views
5

Tôi có một số lớp thử nghiệmLàm thế nào để thiết lập tên lớp cho đối tượng JavaScript

TestKlass = (function() { 

    function TestKlass(value) { 
     this.value = value != null ? value : 'hello world'; 
     console.log(this.value); 
    } 

    return TestKlass; 

})(); 

x = new TestKlass; 
x instanceof TestKlass; (gives true) 

Tôi có đối tượng trống mới

y = {} 
y instanceof Object 

Tôi có thể tìm thấy bất kỳ cách để thiết lập bất kỳ thuộc tính cho y, một cái gì đó như thế này

y.__proto__ = x.__proto__ 
y.constructor.prototype = x.constructor.prototype 

để có kết quả này

y instanceof TestKlass => true 

======================== ========

UPD:

So. Mục đích chính của tôi - đó là tạo ra hàm CLONE. Bây giờ giải pháp của tôi làm việc cho tôi. Hãy nhìn vào mã này:

Javascript JS đối tượng bản sao

Object._clone = function(obj) { 
    var clone, property, value; 
    if (!obj || typeof obj !== 'object') { 
    return obj; 
    } 
    clone = typeof obj.pop === 'function' ? [] : {}; 
    clone.__proto__ = obj.__proto__; 
    for (property in obj) { 
    if (obj.hasOwnProperty(property)) { 
     value = obj.property; 
     if (value && typeof value === 'object') { 
     clone[property] = Object._clone(value); 
     } else { 
     clone[property] = obj[property]; 
     } 
    } 
    } 
    return clone; 
}; 

CoffeeScript JS đối tượng bản sao

# Object clone 
Object._clone = (obj) -> 
    return obj if not obj or typeof(obj) isnt 'object' 
    clone = if typeof(obj.pop) is 'function' then [] else {} 

    # deprecated, but need for instanceof method 
    clone.__proto__ = obj.__proto__ 

    for property of obj 
    if obj.hasOwnProperty property 
     # clone properties 
     value = obj.property 
     if value and typeof(value) is 'object' 
     clone[property] = Object._clone(value) 
     else 
     clone[property] = obj[property] 

    clone 

Bây giờ bạn có thể thử để làm điều đó

A = new TestKlass 
B = Object._clone(A) 
B instanceof TestKlass => true 

Đó là công việc tốt với Moz FF 13. Nhưng tôi nghĩ nó không phải là trình duyệt chéo. và proto không còn được dùng nữa.

Tôi nghĩ rằng không có giải pháp phổ quát. Nhưng có lẽ Nó sẽ hữu ích cho ai đó.

+0

'y.constructor = x.constructor'? Chỉ cần đoán ... Thực sự, tuy nhiên, bạn không nên quan tâm đến các loại. Ý tôi là, nếu có một cách dễ dàng để giả mạo chúng, chúng có gì tốt? – cHao

+0

Câu trả lời có cung cấp cho bạn đủ thông tin không? Nếu vậy, bạn có thể chấp nhận câu trả lời không? :-) –

+0

Tôi chỉ đang tìm giải pháp tốt nhất. Tôi sẽ đánh dấu câu trả lời hay nhất sau khi tìm hiểu sâu trang này http://javascript.ru/tutorial/object/inheritance (tiếng Nga) –

Trả lời

1

Có lẽ bạn nên đọc phần sau answer trước tiên. Những gì bạn đang cố gắng đạt được thực sự đơn giản. Tuy nhiên trước khi tôi giải thích chúng ta hãy nhìn vào các giải pháp của bạn:

Giải pháp 1

y.__proto__ = x.__proto__; 

tôi sẽ không khuyên bạn nên làm điều này như __proto__ bất động sản tại deprecated là. Mã trên sẽ không hoạt động trong Rhino.

Giải pháp 2

y.constructor.prototype = x.constructor.prototype; 

Đây là một giải pháp rất xấu. Lý do là y.constructor thực sự là y.__proto__.constructor và kể từ y là một đối tượng y.__proto__ giống như Object.prototype.Điều này có nghĩa là y.constructor giống với Object và về cơ bản bạn đang thay đổi thuộc tính prototype của Object. Điều này có khả năng có thể phá vỡ mã khác trên trang của bạn. Tôi mạnh mẽ không khuyến khích thực hành này.

Giải pháp 3 (giải pháp của tôi)

gì bạn muốn làm chỉ đơn giản là thay đổi nội [[proto]] tài sản của một đối tượng. Vì không có cách thức nền tảng chéo nào để làm như vậy, chúng ta cần phải sử dụng một hack. Một giải pháp đơn giản sẽ là tạo một đối tượng mới với thuộc tính mong muốn __proto__ và đặt getters và setters trên nó để thay đổi đối tượng gốc. Nó sẽ là như sau:

function setPrototypeOf(object, prototype) { 
    var constructor = function() { 
     for (var key in object) { 
      if (object.hasOwnProperty(key)) { 
       (function (key) { 
        Object.defineProperty(this, key, { 
         get: function() { 
          return object[key]; 
         }, 
         set: function (value) { 
          object[key] = value; 
         }, 
         enumerable: true 
        }); 
       }).call(this, key); 
      } 
     } 
    }; 

    constructor.prototype = prototype; 

    return new constructor; 
} 

Sau khi tất cả điều này bạn cần phải làm là:

y = setPrototypeOf(y, TestKlass.prototype); 

Đây là một fiddle làm việc.

Edit:

Vấn đề với chức năng clone của bạn là nó chỉ bắt chước các đối tượng và mảng. Bạn quên tính đến các hàm cũng được chuyển qua tham chiếu. Vì vậy, khi bạn sao chép một đối tượng có các phương thức mà close over trạng thái bên trong của đối tượng, đối tượng và bản sao của nó sẽ chia sẻ cùng trạng thái bên trong. Xem sau fiddle:

function Value(value) { 
    this.get = function() { 
     alert(value); 
    }; 
    this.set = function (newValue) { 
     value = newValue; 
    }; 
} 

var a = new Value(5); 
var b = Object._clone(a); 
b.set(10);    // setting b to 10 also sets a to 10 
a.get();     // alerts 10, should alert 5 

Có hoàn toàn không có cách nào trong hoạt Javascript để sao chép trạng thái nội tại của một đối tượng để nhân bản đối tượng và mảng trong JavaScript sẽ chỉ làm việc cho các đối tượng mà không tiếp xúc với đóng cửa như các phương pháp.

Để biết thêm về các vấn đề với nhân bản đối tượng trong JavaScript, hãy đọc số answer này. Nhấp vào số link sau đây để đọc câu trả lời của John Resig.

1

obj instanceof SomeConstructor kiểm tra xem SomeConstructor có được tìm thấy ở bất kỳ đâu trong chuỗi mẫu obj hay không.

Nếu bạn muốn thừa kế, bạn cần đặt .prototype của FirstConstructor thành đối tượng SomeConstructor mới được tạo.

SomeConstructor = function() {} 
FirstConstructor = function() {} 
FirstConstroctor.prototype = new SomeConstructor(); 

var y = new FirstConstroctor(); 
y instanceof FirstConstructor; // true 
y instanceof SomeConstructor ; // true, it bubbles from FirstConstructor.__proto__ to SomeConstructor 
Các vấn đề liên quan