12

Kiểm tra mã này. Đây là một đối tượng JavaScript rất đơn giản mà được triển khai sử dụng Module Pattern (và bạn có thể xem ví dụ trực tiếp tại this fiddle address)Hỗ trợ getter JavaScript trong IE8

var human = function() { 
    var _firstName = ''; 
    var _lastName = '' 
    return { 
     get firstName() { 
      return _firstName; 
     }, get lastName() { 
      return _lastName; 
     }, set firstName(name) { 
      _firstName = name; 
     }, set lastName(name) { 
      _lastName = name; 
     }, get fullName() { 
      return _firstName + ' ' + _lastName; 
     } 
    } 
}(); 
human.firstName = 'Saeed'; 
human.lastName = 'Neamati'; 
alert(human.fullName); 

Tuy nhiên, IE8 không hỗ trợ JavaScript getset từ khóa. Cả hai bạn có thể kiểm tra nó và xem MDN.

Tôi nên làm gì để làm cho tập lệnh này tương thích với IE8?

Trả lời

22

Tôi nên làm gì để làm cho tập lệnh này tương thích với IE8?

Thay đổi hoàn toàn. Ví dụ, thay vì sử dụng các thuộc tính accessor, sử dụng một sự kết hợp của các thuộc tính bình thường và chức năng:

human.firstName = 'Saeed'; 
human.lastName = 'Neamati'; 
alert(human.getFullName()); 

Một vài người khác đề nghị sử dụng một đối tượng DOM trong IE và thêm các thuộc tính sử dụng Object.defineProperty(). Trong khi nó có thể làm việc, tôi muốn khuyên bạn nên chống lại phương pháp này vì nhiều lý do, một ví dụ là rằng mã bạn viết có thể không tương thích trên mọi trình duyệt:

var human = document.createElement('div'); 
Object.defineProperty(human, 'firstName', { ... }); 
Object.defineProperty(human, 'lastName', { ... }); 
Object.defineProperty(human, 'children', { value: 2 }); 

alert(human.children); 
//-> "[object HTMLCollection]", not 2 

Điều này đúng của ít nhất Chrome. Dù bằng cách nào, việc viết mã hoạt động trên tất cả các trình duyệt bạn muốn hỗ trợ cũng an toàn hơn và dễ dàng hơn. Bất kỳ tiện ích nào bạn có được từ việc có thể viết mã để tận dụng lợi thế của getters và setters đã bị mất trên mã phụ bạn đã ghi cụ thể nhắm mục tiêu Internet Explorer 8.

Điều này, tất nhiên, ngoài việc giảm hiệu suất, thực tế là bạn sẽ không thể sử dụng vòng lặp for...in trên đối tượng và sự nhầm lẫn tiềm năng xảy ra sau đó khi bạn sử dụng thuộc tính mà bạn cho rằng mình đã xác định nhưng đã có sẵn trên đối tượng DOM.

+0

Tôi có nghĩa là làm cách nào để mã của tôi tương thích ngược. Giải pháp để triển khai thực hiện một mô-đun mô-đun trong JavaScript hoạt động trong IE8 là gì, và nó có các đặc tính getter như thế nào? –

+1

@SaeedNeamati Nếu bạn thực sự muốn getters/setters, bạn có thể làm hai việc: 1) tạo các phương thức như '.getMyValue' và' .setMyValue', hoặc 2) tạo các phương thức chấp nhận một giá trị hoặc trả về nếu không có giá trị nào (giống như những gì jQuery làm với một số phương thức - nếu bạn đưa ra một giá trị nó đặt, nếu bạn không đưa ra một giá trị nó nhận được). –

+1

Câu trả lời tồi tệ nhất bao giờ hết. Không thể tin rằng nó có nhiều upvotes. – DontVoteMeDown

8

Bạn có thể không (as Andy answered)

Việc thay thế gần nhất sẽ là

var human = function() { 
    var _firstName = ''; 
    var _lastName = ''; 

    return { 
     firstName: function() { 
      if (arguments.length === 1) { 
       _firstName = arguments[0]; 
      } 
      else { 
       return _firstName; 
      } 
     }, 
     lastName: function() { 
      if (arguments.length === 1) { 
       _lastName = arguments[0]; 
      } 
      else { 
       return _lastName; 
      } 
     }, 
     fullName: function() { 
      return _firstName + ' ' + _lastName; 
     } 
    }; 
}(); 

human.firstName('Saeed'); 
human.lastName('Neamati'); 

alert(human.fullName()); 

Demo tại http://jsfiddle.net/gaby/WYjqB/2/

+0

IE luôn luôn hút. Mặc dù Microsoft có nhiều sản phẩm tốt, nhưng tôi thực sự ghét Microsoft, chỉ vì IE của nó. –

+1

@Seed: thực sự, đây là một kịch bản mà nó không phải là lỗi của Microsoft. Getters và setters là một bổ sung gần đây cho đặc tả ECMA-262. IE 9 hỗ trợ getters và setters thông qua 'Object.defineProperty()'. Triển khai bạn đang sử dụng (Mozilla) là không chuẩn và không được bảo đảm hoạt động trên nhiều trình duyệt. –

+1

Nhưng @Gaby, Firefox đã hỗ trợ phiên bản này từ phiên bản 2.0, Chrome từ phiên bản 1, Safari từ phiên bản 3.5 và Opera từ phiên bản 9.5. Vì vậy, làm thế nào là, mà IE8 không thể hỗ trợ một điều như vậy? –

4

Kiểm tra nó trên http://robertnyman.com/2009/05/28/getters-and-setters-with-javascript-code-samples-and-demos/

Tương lai, và tiêu chuẩn ECMAScript ized cách, mở rộng các đối tượng trong tất cả các loại cách là thông qua Object.defineProperty. Đây là cách Internet Explorer chọn triển khai getters và setters, nhưng nó là thật không may cho đến nay chỉ có sẵn trong Internet Explorer 8 và không có trong bất kỳ trình duyệt web nào khác trong số . Ngoài ra, IE 8 chỉ hỗ trợ nó trên các nút DOM, nhưng các phiên bản tương lai được lên kế hoạch để hỗ trợ nó trên các đối tượng JavaScript như là .

Bạn có thể tìm thấy các trường hợp thử nghiệm trên cùng một trang web tại http://robertnyman.com/javascript/javascript-getters-setters.html#object-defineproperty

Object.defineProperty(document.body, "description", { 
    get : function() { 
     return this.desc; 
    }, 
    set : function (val) { 
     this.desc = val; 
    } 
}); 
document.body.description = "Content container"; 

Kết quả:

document.body.description = "Content container" 
+0

Đã sửa kết quả. –

5

IE8 hỗ trợ getter và setter trên các nút DOM, vì vậy nếu bạn thực sự muốn có getters và setters, bạn có thể làm điều này:

var objectForIe8 = $("<div></div>")[0];  
Object.defineProperty(objectForIe8, "querySelector", { 
    get: function() { 
     return this.name; 
    }, 
    set: function(val) { 
     this.name = val+", buddy"; 
    } 
}); 
// notice you can overwrite dom properties when you want to use that property name 
objectForIe8.querySelector = "I'm not your guy"; 

alert(objectForIe8.querySelector); 

Lưu ý rằng điều này mang lại cho bạn một hiệu suất khá đáng kể, vì vậy tôi sẽ không sử dụng kỹ thuật này nếu bạn cần tạo hàng nghìn đối tượng như thế này. Nhưng nếu bạn không lo lắng về hiệu suất của vật thể đặc biệt này, nó sẽ đẩy bạn qua. Và nếu bạn không quan tâm đến hiệu năng ie8 và chỉ muốn nó hoạt động, hãy sử dụng kỹ thuật này cho ie8 và bạn vàng:)

+1

Có một số vấn đề với cách tiếp cận này làm cho nó quá phức tạp và không thực sự đáng giá. Ví dụ, sự thừa kế nguyên mẫu đi ra ngoài cửa sổ, các vấn đề về hiệu năng tạo đối tượng mà bạn đề cập, các xung đột đặt tên có thể xảy ra, v.v. Nó xa "vàng". –

+2

Trong khi không phải là một giải pháp vàng (cơ hội chất béo mà trong khi sử dụng IE), nó trong thực tế trả lời câu hỏi ... –

+2

Cảm ơn. Tất cả những gì tôi cần là một lớp nhỏ gọn và đơn giản để lưu trữ/lấy các giá trị trong suốt thời gian của phiên. Điều này giúp tôi dễ dàng khai báo và sử dụng tài sản khi cần thiết. – gouderadrian

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