面相对象(二)
原型鏈:實例對象與原型之間的連接,叫做原型鏈
原型鏈的最外層 : Object.prototype
function Aaa(){
//構造函數
}
Aaa.prototype.num=30p; //擴展原型方法
var a1=new Aaa();? //創建對象
原型檢測相關:
hasOwnProperty:看是不是對象自身的屬性
具體概念:用來判斷一個對象是否有你給出名稱的屬性或對象,不過需要注意:次方法無法檢測到原型鏈中是否具有該屬性,該屬性必須是對象本身的一個成員
1 var arr=[]; 2 arr.num=10; 3 Array.prototype.num2=20; 4 console.log(arr.hasOwnProperty('num'));//true 5 console.log(arr.hasOwnProperty('num2'));//false?isPrototypeOf:是用來判斷原型鏈對象是否存在指定對象實例中,則返回true,否則返回false
?constructor? 屬性返回對創建此對象的數組函數的引用
1 function Aaa(){ 2 3 } 4 var a1=new Aaa(); 5 alert(a1.constructor);//function Aaa(){}? function Aaa(){
? }
? alert(Aaa.prototype.constructor==Aaa); //true 每一個函數都會自動生成的
Object.constructor
我們在定義函數的時候,函數定義的時候函數本身就會默認有一個prototype的屬性,
而我們如果用new 運算符來生成一個對象的時候就沒有prototype屬性。我們來看一個例子,來說明這個
1 function a(c){ 2 this.b = c; 3 this.d =function(){ 4 alert(this.b); 5 } 6 } 7 var obj = new a('test'); 8 alert(typeof obj.prototype);//undefine 9 alert(typeof a.prototype);//objecta.prototype 包含了2個屬性,一個是constructor ,另外一個是__proto__
這個constructor ?就是我們的構造函數a,這個也很容易理解。
那么__proto__ 是什么呢?
這就涉及到原型鏈的概念
每個對象都會在其內部初始化一個屬性,就是__proto__,當我們訪問一個對象的屬性時,如果對象內部不存在
這個屬性就會到__proto__里找這個屬性,這個__proto__又會有自己的__proto__,于是一直走下去。
obj.__proto__===a.prototype //true
同理,這里我們分析出new運算符做了那些事情
1.var obj={};? ?也就是說初始化一個對象obj
2.obj.__proto__=a.prototype;
3.a.call(obj) 也就是構造obj,也可以稱為初始化obj
?instanceof:對象與構造函數在原型鏈上是否有關系
1 function Aaa(){ 2 } 3 4 var a1 = new Aaa(); 5 6 alert( a1 instanceof Object ); //true 7 8 var arr = []; 9 10 alert( arr instanceof Array );toString() :系統對象下面都是自帶的,自己寫的對象通過原型鏈找object下面的
將邏輯值轉換成字符串
繼承:子類不影響父類,子類可以繼承父類的一些功能
屬性的繼承:調用父類的構造函數call
方法的繼承: for? in :拷貝繼承(jquery也是采用拷貝繼承extend)
<style> #div1{ width:100px; height:100px; background:red; position:absolute;} #div2{ width:100px; height:100px; background:yellow; position:absolute; left:100px;} </style> <script> window.onload=function(){var d1=new Drag('div1');d1.init();var d2=new ChildDrag('div2');d2.init(); }function Drag(id){this.obj=document.getElementById(id);this.disX=0;this.disY=0; } Drag.prototype.init=function(){var This=this;this.obj.onmousedown = function(ev){var ev = ev || window.event;This.fnDown(ev);document.onmousemove = function(ev){var ev = ev || window.event;This.fnMove(ev);};document.onmouseup = function(){This.fnUp();};return false;}; }; Drag.prototype.fnDown = function(ev){this.disX = ev.clientX - this.obj.offsetLeft;this.disY = ev.clientY - this.obj.offsetTop; }; Drag.prototype.fnMove = function(ev){this.obj.style.left = ev.clientX - this.disX + 'px';this.obj.style.top = ev.clientY - this.disY + 'px'; }; Drag.prototype.fnUp = function(){document.onmousemove = null;document.onmouseup = null; };function ChildDrag(id){ //子類Drag.call(this,id);//這個this指LimitDrag new的對象 }extend(ChildDrag.prototype,Drag.prototype);//實現繼承父類方法 function extend(obj1,obj2){for(var attr in obj2){obj1[attr] = obj2[attr];} } </script> </head><body> <div id="div1"></div> <div id="div2"></div>?js沒有類的概念,把JS中的構造函數看做類
要做屬性和方法繼承的時候要分開繼承? ? ?類式繼承
1 //類:JS是沒有類概念的,把JS中的構造函數看做類 2 //類式繼承:利用構造函數(類)繼承的方式 3 function Aaa(){ 4 this.name=[1,2,3]; 5 } 6 Aaa.prototype.showName=function(){ 7 alert(this.name); 8 } 9 10 function Bbb(){ //子類 11 Aaa.call(this); 12 } 13 //這四句必須的 14 var F=function(){}; 15 F.prototype=Aaa.prototype; 16 Bbb.prototype=new F();//直接復制把所有東西度覆蓋了 17 Bbb.prototype.constructor=Bbb; //修正指向問題 18 var b1=new Bbb(); 19 b1.name.push(4); 20 alert( b1.name );//1,2,3,4 21 var b2 = new Bbb(); 22 23 alert( b2.name );//1,2,3?原型繼承
1 //原型繼承: 無new的對象 2 var a={ 3 name:'小明' 4 }; 5 var b=cloneobj(a); 6 alert(b.name); 7 function cloneobj(obj){ 8 var F=function(){}; 9 F.prototype=obj; 10 return new F(); 11 }?
轉載于:https://www.cnblogs.com/zhihou/p/8108737.html
總結
- 上一篇: 正负值地处理以及添加回调函数小案例
- 下一篇: 分页原理+软件架构师