DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> 關於JavaScript >> Javascript實例代碼講解instanceof操作符
Javascript實例代碼講解instanceof操作符
編輯:關於JavaScript     

在JavaScript中,我們可以用instanceof操作符來判斷對象是否是某個類的實例,如果obj instaceof Class返回true,那麼我們認為obj是Class的實例,obj要麼由Class創建,要麼由Class的子類創建。來自Java或其他強類型語言的開發者一定認為如果obj instaceof Class返回true,那麼obj肯定擁有Class的所有屬性。事實是這樣麼?我們看下面的代碼:

Js代碼

  1. function ClassA()
  2. {
  3. this.ma = 'ClassA';
  4. }
  5. ClassA.prototype.fa = function(){return 'prototype function';};
  6. function ClassB()
  7. {
  8. this.mb = 'ClassB';
  9. }
  10. ClassB.prototype = ClassA.prototype;
  11. var obja = new ClassA();
  12. alert(('ma' in obja) + ' ' + obja.hasOwnProperty('ma')); //output true true
  13. alert(('mb' in obja) + ' ' + obja.hasOwnProperty('mb')); //output false false
  14. alert(('fa' in obja) + ' ' + obja.hasOwnProperty('fa')); //output true false
  15. alert(('fb' in obja) + ' ' + obja.hasOwnProperty('fb')); //output true false
  16. alert(obja instanceof ClassA); //output true
  17. alert(obja instanceof ClassB); //output true
  18. var objb = new ClassB();
  19. alert(('ma' in objb) + ' ' + objb.hasOwnProperty('ma')); //output false false
  20. alert(('mb' in objb) + ' ' + objb.hasOwnProperty('mb')); //output true true
  21. alert(('fa' in objb) + ' ' + objb.hasOwnProperty('fa')); //output true false
  22. alert(('fb' in objb) + ' ' + objb.hasOwnProperty('fb')); //output true false
  23. alert(objb instanceof ClassA); //output true
  24. alert(objb instanceof ClassB); //output true

 

在這段代碼中,我們定義了兩個類,ClassA與ClassB,還給ClassA創建了原型方法fa,給ClassB創建了原型方法fb,並分別創建了對象obja與objb。直覺上,我們並不認為ClassA與ClassB是同一個類,所以obja不是ClassB的實例,objb也不是ClassA的實例,而且obja不會擁有屬性fb,objb也不會擁有屬性fa,但是運行結果告訴我們,JavaScript並不這樣認為。obja與objb都擁有屬性fa與fb,它們既是ClassA的實例也是ClassB的實例。下面我們分析一下原因。(斑頭雁原創:http://bantouyan.iteye.com)

ClassA的prototype與ClassB的prototype是同一個對象,所以給ClassA增加原型方法fa會影響到ClassB,給ClassB增加的原型方法fb也會影響到ClassA,所以obja與objb都擁有屬性fa與fb,這一點也比較容易理解。oba沒有ClassB的實例屬性mb但卻是ClassB的實例,objb也沒有ClassA的實例屬性ma但卻是ClassA的實例,這說明instanceof的判斷與實例屬性無關。既然instanceof與實例屬性無關,那麼它就跟原型屬性有關。事實上,JavaScript根據原型判定instanceof的運算結果。(斑頭雁原創:http://bantouyan.iteye.com)

我們知道同一個構造函數所創建的對象與這個構造函數共享同一個原型(只不一般不能直接訪問過對象的原型),而ClassA與ClassB也共享同一個原型,那麼obja與objb也共享同一個原型,所以可以這樣認為,如果對象與類共享一個原型,那麼對象就是這個類的實例,instanceof運算就返回true。下面我們看一下繼承的情況。(斑頭雁原創:http://bantouyan.iteye.com)

Js代碼

  1. function ClassA()
  2. {
  3. this.ma = 'ClassA';
  4. }
  5. ClassA.prototype.fa = function(){return 'prototype function fa';};
  6. function ClassB()
  7. {
  8. this.mb = 'ClassB';
  9. }
  10. ClassB.prototype = ClassA.prototype;
  11. ClassB.prototype.fb = function(){return 'prototype function fb';};
  12. function ClassC()
  13. {
  14. this.mc = 'ClassC';
  15. }
  16. ClassC.prototype = new ClassB();
  17. ClassC.prototype.fc = function(){return 'prototype function fc';};
  18. var objc = new ClassC();
  19. alert(objc instanceof ClassB); //output true
  20. alert(objc instanceof ClassA); //output true
  21. alert(('ma' in objc) + ' ' + objc.hasOwnProperty('ma')); //output false false
  22. alert(('mb' in objc) + ' ' + objc.hasOwnProperty('mb')); //output true false
  23. alert(('mc' in objc) + ' ' + objc.hasOwnProperty('mc')); //output true true
  24. alert(('fa' in objc) + ' ' + objc.hasOwnProperty('fa')); //output true false
  25. alert(('fb' in objc) + ' ' + objc.hasOwnProperty('fb')); //output true false
  26. alert(('fc' in objc) + ' ' + objc.hasOwnProperty('fc')); //output true false

 

ClassC采用原型鏈方法繼承了ClassB,所以ClassC的對象objc是ClassB的實例,但是運行結果告訴我們,objc也是ClassA的實例。objc是ClassC的實例,所以objc與ClassC共享一個原型。ClassC的原型是ClassB的實例,所以ClassC的原型的原型與ClassB的原型是同一個原型,而ClassB與ClassA共享同一個原型,所以ClassC的原型的原型與ClassA的原型是同一個原型,即objc的原型的原型與ClassA的原型是同一個原型。由此看來,instanceof可以根據對象原型的原型,即原型鏈上的原型,判定運算的結果,即如果類的原型與對象原型鏈上的某一個原型是同一個對象,那麼instanceof運算將返回true,否則返回false。下面我們用一段更長的代碼來驗證這個結論。(斑頭雁原創:http://bantouyan.iteye.com)

Js代碼

  1. function ClassA()
  2. {
  3. this.ma = 'ClassA';
  4. }
  5. ClassA.prototype.fa = function(){return 'prototype function fa';};
  6. function ClassB()
  7. {
  8. this.mb = 'ClassB';
  9. }
  10. ClassB.prototype = ClassA.prototype;
  11. ClassB.prototype.fb = function(){return 'prototype function fb';};
  12. function ClassC()
  13. {
  14. this.mc = 'ClassC';
  15. }
  16. ClassC.prototype = new ClassB();
  17. ClassC.prototype.fc = function(){return 'prototype function fc';};
  18. function ClassD()
  19. {
  20. this.md = 'ClassD';
  21. }
  22. ClassD.prototype = ClassC.prototype;
  23. ClassC.prototype.fd = function(){return 'prototype function fd';};
  24. function ClassE()
  25. {
  26. this.me = 'ClassE';
  27. }
  28. ClassE.prototype = new ClassD();
  29. ClassE.prototype.fe = function(){return 'prototype function fe';};
  30. var obje = new ClassE();
  31. alert(obje instanceof ClassA); //output true
  32. alert(obje instanceof ClassB); //output true
  33. alert(obje instanceof ClassC); //output true
  34. alert(obje instanceof ClassD); //output true
  35. alert(obje instanceof ClassE); //output true
  36. alert(('ma' in obje) + ' ' + obje.hasOwnProperty('ma')); //output false false
  37. alert(('mb' in obje) + ' ' + obje.hasOwnProperty('mb')); //output true false
  38. alert(('mc' in obje) + ' ' + obje.hasOwnProperty('mc')); //output false false
  39. alert(('md' in obje) + ' ' + obje.hasOwnProperty('md')); //output true false
  40. alert(('me' in obje) + ' ' + obje.hasOwnProperty('me')); //output true true
  41. alert(('fa' in obje) + ' ' + obje.hasOwnProperty('fa')); //output true false
  42. alert(('fb' in obje) + ' ' + obje.hasOwnProperty('fb')); //output true false
  43. alert(('fc' in obje) + ' ' + obje.hasOwnProperty('fc')); //output true false
  44. alert(('fd' in obje) + ' ' + obje.hasOwnProperty('fd')); //output true false
  45. alert(('fe' in obje) + ' ' + obje.hasOwnProperty('fe')); //output true false

 

ClassA的原型與ClassB的原型共享同一個對象,ClassC的原型與ClassD的原型也共享一個對象,而ClassC是ClassB的子類,ClassE是ClassD的子類,而obje是ClassE的實例。所以obje的原型鏈的第一個原型是ClassE的原型,它是ClassD的實例,故第二個原型是ClassD的原型,也就是ClassC的原型,ClassC的原型是ClassB的實例,所以原型鏈上第三個原型是ClassB的原型,也就是ClassA的原型。所以,ClassA、ClassB、ClassC、ClassD與ClassE的原型都在對象obje的原型鏈上,所以obje是這些類的實例。這也驗證了前面的結論,即如果類的原型與對象原型鏈上的某一個原型是同一個對象,那麼instanceof運算將返回true。雖然obje是ClassA、ClassC的實例,但是它並沒有ClassA的實例屬性ma,ClassC的實例屬性mc。

綜合前面的論述與驗證,我們可以得出結論,如果obj instanceof Class返回true,那麼Class的原型與obj原型鏈上的某個原型是同一個對象,但這並不意味著obj擁有Class的所有實例屬性(但肯定擁有Class的所有原型屬性)。

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved