2012-04-04 31 views
6

Sau khi thử nghiệm quá nhiều thời gian, tôi đã phát hiện ra rằng phương pháp __proto__ hoặc Object.getPrototypeOf() là cách chính xác để đi qua chuỗi nguyên mẫu trong đối tượng DOM.Sự khác biệt về hành vi của Firefox và chrome giữa constructor.prototype?

Sử dụng chuỗi constructor.prototype thực sự không đi qua chuỗi nguyên mẫu trong cả hai trình duyệt. (Trong khi đây là cách được xác định trong tiêu chuẩn ECMA, thuộc tính mẫu của hàm tạo là đối tượng mẫu của bạn).

Bất kỳ gợi ý hoặc nhận xét được hoan nghênh ...

p1 = document.getElementById("test"); // div element 

//Prototype Object of p1 
p2 = element.constructor.prototype; 

//Prototype object of p2 
p3 = element.constructor.prototype.constructor.prototype; 

console.log(p2 === p3); // true in chrome(howcome they same ?), false in firefox 

q2 = element.__proto__; 
q3 = element.__proto__.__proto__; 

console.log(q2 === q3); // false in both browser 

Trả lời

0

Tôi nghĩ rằng bạn hiểu lầm như thế nào constructor/nguyên mẫu hoạt động.

Với chức năng hàm tạo, mẫu .prototype của nó sẽ là nguyên mẫu của những thứ được xây dựng với nó. Nguyên mẫu .constructor trỏ trở lại hàm khởi tạo.

Vì vậy, cụ thể, Element.prototype.constructor === Element nên giữ. Nó không nhất thiết trong trình duyệt do lỗi. Đây là lý do tại sao bạn thấy p2 == p3 trong Chrome.

1

Tôi hoàn toàn đồng ý với Boris ... Bạn nên tìm kiếm ở đây để biết thêm chi tiết (https://www.google.com/search?q=javascript+prototype+chain) nhưng về cơ bản nếu bạn muốn duyệt các yếu tố trong các đối tượng DOM, bạn chỉ cần làm dưới đây như thế này:

function exploreElement(element){ 
     contentToString = ""; 
     for (var i in element){ 
      contentToString += i + " : " + element[i] + "<br />"; 
     } 
     document.write(contentToString); 
    } 
    exploreElement(document); 

Nguyên mẫu và proto là một cái gì đó hoàn toàn khác nhau ...

Nếu bạn có một hàm constructor như thế này:

function SomeObject(){ 
     this.__proto__.id = "instance_default_name"; 
     SomeObject.id = "SomeObject"; 
     // __proto__ HERE to access the prototype!!! 
    } 

Sau đó bạn có thể thêm các phương pháp để Constructor này qua nguyên mẫu (tôi giả sử rằng bạn có một div trống với một id "myInstance" và khác với id "test" trong tài liệu):

SomeObject.prototype.log = function(something){ 
     document.getElementById("myInstance").innerHTML += something + "<br />"; 
    } 

Thêm một số phương pháp cho mục đích thử nghiệm:

SomeObject.prototype.setId = function(id){ 
    this.id = id; 
} 
SomeObject.prototype.getId = function(){ 
    return this.id; 
} 
SomeObject.prototype.getClassName = function(){ 
    return SomeObject.id; 
} 

Sau đó, bạn có thể nhanh chóng SomeObject với các nhà điều hành mới và làm một số xét nghiệm như thế này:

myInstance = new SomeObject(); 
myInstance.setId("instance_1"); 
aDivElement = document.getElementById("test"); 
aDivElement.style.backgroundColor = "rgb(180,150,120)"; 
myInstance.log("p1 = " + aDivElement); 
// [object HTMLDivElement] 
myInstance.log("p1 backgroundColor = " + (aDivElement.style.backgroundColor)); 
myInstance.log("myInstance = " + myInstance); 
// [object Object] an instance of SomeObject 
myInstance.log("myInstance.constructor = " + myInstance.constructor); 
// function SomeObject() { this.__proto__.id = "instance_default_name"; SomeObject.id = "SomeObject"; } 
myInstance.log("myInstance.constructor.prototype = " + myInstance.constructor.prototype); 
// .prototype WHEN CALLED by the instance NOT __proto__ 
// The constructor of myInstance is SomeObject and the prototype of SomeObject is the prototype of all instances of SomeObject 
myInstance.log("myInstance.id = " + myInstance.getId()); 
// id for the instance of SomeObject that you have instanciated 
myInstance.log("SomeObject.prototype.id = " + SomeObject.prototype.getId()); 
// id by default of the prototype 
myInstance.log("myInstance.constructor.prototype.id = " + myInstance.constructor.prototype.getId()); 
// id by default of the prototype 
myInstance.log("myInstance.getClassName() = " + myInstance.getClassName()); 
// myInstance.getClassName() = SomeObject 

Tôi không biết điều này có nói chuyện với bạn một chút hay không, nhưng tôi hy vọng điều này sẽ giúp bạn tìm kiếm. Trân trọng. Nicolas

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