2017-09-12 107 views
0

this SO answer他說Object.keys()得到返回true for obj.hasOwnProperty(key)的那些對象本身定義的屬性(但下面的代碼返回4 keys,也產生錯誤,是混淆了我。Object.keys()返回屬性

(function() { 
 
    "use strict"; 
 
    var buttons = document.getElementsByClassName('remove'); 
 
    console.log("No of keys: ", Object.keys(buttons).length); 
 
    for (var i in Object.keys(buttons)) { 
 
     buttons[i].onclick = function() { 
 
      this.parentElement.remove(); 
 
      console.log(this.id); 
 
     }; 
 
    } 
 
})();
<div>Some entry here 
 
    <button id="0" class="remove">Remove</button> 
 
</div> 
 
<div>Another entry here 
 
    <button id="1" class="remove">Remove</button> 
 
</div>

如何在JavaScript正確做到這一點?

+0

'但下面的代碼返回4鍵'nope,2在firefox –

+0

我使用鉻。 – Srinivas

+0

Chrome中有4個,Firefox中有2個。由於ID是'0'和'1',因此HTMLCollection在基於索引的密鑰和基於ID的密鑰之間發生衝突。我猜測,因爲索引是Chrome瀏覽器將它們視爲不等於字符串ID的數字,儘管'Object.keys'然後將它們全部轉換爲字符串,所以最終以'['0','1' ,'0','1']'。 – skirtle

回答

1

因此,這裏是如何你會使用for循環遍歷所有的buttons從原始代碼:

(function() { 
 
    "use strict"; 
 
    var buttons = document.getElementsByClassName('remove'); 
 

 
    console.log(buttons); 
 
    
 
    for (var index = 0 ; index < buttons.length ; ++index) { 
 
     buttons[index].onclick = function() { 
 
      this.parentElement.remove(); 
 
      console.log(this.id); 
 
     }; 
 
    } 
 
})();
<div>Some entry here 
 
    <button id="a" class="remove">Remove</button> 
 
</div> 
 
<div>Another entry here 
 
    <button id="b" class="remove">Remove</button> 
 
</div>

注意,buttons對象是HTMLCollection。這通過索引和id暴露元素。在你原來的例子中,你的ID是01,在這種情況下這很令人困惑,因爲它會導致它們與索引衝突。 Object.keys(buttons)返回['0', '1', '0', '1'],這有點奇怪,可能是因爲一些數字/字符串shenanigans。我已將示例中的ID更改爲ab,因此現在Object.keys(buttons)將爲['0', '1', 'a', 'b']

+0

這實際上是爲什麼它不起作用的正確答案,HTMLCollection通過索引和ID公開了元素,並且OP的奇怪ID被誤導,使得它看起來像在Chrome中由索引公開兩次的元素。 – adeneo

+0

@skirtle謝謝澄清..... – Srinivas

1

不僅爲這個true for obj.hasOwnProperty(key)條件,但人因此稱爲enumerable的屬性屬性之一必須也設置爲true

你的代碼如何?讓我們看看buttons究竟是什麼。你會發現這是一個包含7個屬性的對象。在Chrome中,只有4個屬性中顯示,因爲它們是可枚舉

(function() { 
 
    "use strict"; 
 
    var buttons = document.getElementsByClassName('remove'); 
 
    console.log(buttons); 
 
    
 
})();
<div>Some entry here 
 
    <button id="0" class="remove">Remove</button> 
 
</div> 
 
<div>Another entry here 
 
    <button id="1" class="remove">Remove</button> 
 
</div>

所以,當您嘗試執行這段代碼

(function() { 
 
    "use strict"; 
 
    var buttons = document.getElementsByClassName('remove'); 
 

 
    for (var i in Object.keys(buttons)) { 
 
     console.log(i); 
 
    } 
 
    
 
})();
<div>Some entry here 
 
    <button id="0" class="remove">Remove</button> 
 
</div> 
 
<div>Another entry here 
 
    <button id="1" class="remove">Remove</button> 
 
</div>

它實際上得到是的從返回的數組的這是1,2,3,4,但是您的buttons對象中沒有名稱爲2, 3, 4的房產。那麼爲什麼你會得到這個錯誤。使用forEach函數遍歷每個屬性並添加事件偵聽器。

(function() { 
 
    "use strict"; 
 
    var buttons = document.getElementsByClassName('remove'); 
 

 
    Array.prototype.forEach.call(buttons, button => { 
 
     button.addEventListener('click', function() { 
 
      this.parentElement.remove(); 
 
      console.log(this.id); 
 
     }); 
 
    }); 
 
    
 
})();
<div>Some entry here 
 
    <button id="0" class="remove">Remove</button> 
 
</div> 
 
<div>Another entry here 
 
    <button id="1" class="remove">Remove</button> 
 
</div>

+0

謝謝,你能解釋爲什麼元素在控制檯中被重複/重複嗎? – Srinivas

+0

@Srinivas這是一個Chrome問題,如果你在Firefox中看,你會看到兩個。 –