1. 程式人生 > >JS筆記加強版3

JS筆記加強版3

基本類型 加工 定義 cal 類對象 都是 函數 首字母 sna

JS 面向對象及組件開發 JS的面向對象: 1、什麽是面向對象編程 用對象的思想去寫代碼,就是面向對象編程 過程式寫法 面向對象寫法 我們一直都在使用對象 數組 Array 時間 Date var date = new Date(); var arr = new Array(); //[] //我們把系統自帶的對象,叫做系統對象 面向對象編程(OOP)的特點 抽象:抓住核心問題 封裝:只能通過對象來訪問方法 繼承:從已有對象上繼承出新的對象 多態:多對象的不同形態 2、對象的組成 方法(行為、操作)——函數:過程、動態的 屬性——變量:狀態、靜態的 var arr = []; arr.number = 10; //對象下面的變量:叫做對象的屬性
arr.test = function(){ //對象下面的函數 : 叫做對象的方法 alert(123); }; arr.test(); //123 3、創建第一個面向對象程序 為對象添加屬性和方法 Object對象 this指向 創建兩個對象 : 重復代碼過多 //var obj = {}; var obj = new Object(); //創建了一個空的對象 obj.name = ‘小明‘; //屬性 obj.showName = function(){ //方法 //alert(obj.name); alert(this.name); // this指向的就是obj }; obj.showName(); //小明
4、工廠方式 //工廠方式 : 面向對象中的封裝函數 function createPerson(name){
//1.原料 var obj = new Object(); //2.加工 obj.name = name; obj.showName = function(){ alert( this.name ); }; //3.出場 return obj;
} var p1 = createPerson(‘小明‘); p1.showName(); var p2 = createPerson(‘小強‘); p2.showName(); 5、對象的引用 var a = 5; var b = a; b += 3; alert(b); //8 alert(a); //5 基本類型 : 賦值的時候只是值的復制 var a = [1,2,3]; var b = a; b.push(4); alert(b); //[1,2,3,4] alert(a); //[1,2,3,4] 對象類型 : 賦值不僅是值的復制,而且也是引用的傳遞 var a = [1,2,3]; var b = a; b = [1,2,3,4]; // b又重新占了一個內存地址,和原來的無關 alert(b); //[1,2,3,4] alert(a); //[1,2,3] var a = 5; var b = 5; alert(a == b); //基本類型 : 值相同就可以 var a = [1,2,3]; var b = [1,2,3]; alert( a == b ); //false //對象類型 : 值和引用都相同才行 var a = [1,2,3]; var b = a; alert( a==b ); //true 6、工廠方式,構造函數的寫法:
首字母大寫、New 關鍵字提取、This指向為新創建的對象 當new去調用一個函數 : 這個時候函數中的this就是創建出來的對象,而且函數的的返回值直接就是this(隱式返回) 構造函數:new後面調用的函數,即用來創建對象的函數,叫做構造函數 // CreatePerson()構造函數: function CreatePerson(name){ //省略new Object和最後的return obj this.name = name; this.showName = function(){ alert( this.name ); }; } var p1 = new CreatePerson(‘小明‘); p1.showName(); var p2 = new CreatePerson(‘小強‘); p2.showName(); alert( p1.showName == p2.showName ); //false ,值雖然相同,但是引用的 內存地址不同 存在的問題:對象的引用、浪費內存 7、原型-prototype 原型 : 重寫對象方法,讓相同方法在內存中存在一份。就是去改寫對象下面公用的方法或者屬性 , 讓公用的方法或者屬性在內存中存在一份 ( 提高性能 ) 原型 : CSS中的class,可以重用,但優先級沒style高 普通方法 : CSS中的style,不可以重用,優先級高 即原型可以重用,但優先級沒有普通方法高。 var arr = []; arr.number = 10; Array.prototype.number = 20; alert(arr.number); //10 普通方法: var arr = [1,2,3,4,5]; var arr2 = [2,2,2,2,2]; arr.sum = function(){ var result = 0; for(var i=0;i<this.length;i++){ result += this[i]; } return result; }; arr2.sum = function(){ var result = 0; for(var i=0;i<this.length;i++){ result += this[i]; } return result; }; alert( arr.sum() ); //15 alert( arr2.sum() ); //10 原型方法 : var arr = [1,2,3,4,5]; var arr2 = [2,2,2,2,2]; Array.prototype.sum = function(){ var result = 0; for(var i=0;i<this.length;i++){ result += this[i]; } return result; }; alert( arr.sum() ); //15 alert( arr2.sum() ); //10 8、工廠方式之原型:面向對象的寫法: 原型prototype : 要寫在構造函數的下面 function CreatePerson(name){ this.name = name; } CreatePerson.prototype.showName = function(){ alert( this.name ); }; var p1 = new CreatePerson(‘小明‘); p1.showName(); var p2 = new CreatePerson(‘小強‘); p2.showName(); alert( p1.showName == p2.showName ); //true 總結面向對象寫法:構造函數加屬性,原型加方法 function 構造函數(參數){ this.屬性 = 參數; } 構造函數.prototype.方法 = function(){ ... }; 調用寫法: var 對象1 = new 構造函數(); 對象1.方法(); 9、面向對象的例子: 原則: 1)先寫出普通的寫法,然後改成面向對象寫法 2)普通方法變型 3)盡量不要出現函數嵌套函數 4)可以有全局變量 5)把onload中不是賦值的語句放到單獨函數中 改成面向對象: 1)全局變量就是屬性 2)函數就是方法 3)Onload中創建對象 4)改this指向問題 5)事件ev要放到事件函數中: var ev = ev || window.event; return false; 例子:面向對象的選項卡: 第一步:普通方法: <script> window.onload = function(){
var oParent = document.getElementById(‘div1‘); var aInput = oParent.getElementsByTagName(‘input‘); var aDiv = oParent.getElementsByTagName(‘div‘); for(var i=0;i<aInput.length;i++){ aInput[i].index = i; aInput[i].onclick = function(){
for(var i=0;i<aInput.length;i++){
aInput[i].className = ‘‘;
aDiv[i].style.display = ‘none‘;
}
this.className = ‘active‘;
aDiv[this.index].style.display = ‘block‘;
};
} }; </script> 第二步: 先變型: 盡量不要出現函數嵌套函數 可以有全局變量 把onload中不是賦值的語句放到單獨函數中 <script> var oParent = null; var aInput = null; var aDiv = null; window.onload = function(){ oParent = document.getElementById(‘div1‘); aInput = oParent.getElementsByTagName(‘input‘); aDiv = oParent.getElementsByTagName(‘div‘); init(); }; function init(){ for(var i=0;i<aInput.length;i++){ aInput[i].index = i; aInput[i].onclick = change; } } function change(){ for(var i=0;i<aInput.length;i++){ aInput[i].className = ‘‘; aDiv[i].style.display = ‘none‘; } this.className = ‘active‘; aDiv[this.index].style.display = ‘block‘; } </script> 第三步: 全局變量就是屬性 函數就是方法 Onload中創建對象 改this指向問題 <script> window.onload = function(){ var t1 = new Tab(‘div1‘); t1.init(); t1.autoPlay(); var t2 = new Tab(‘div2‘); t2.init(); t2.autoPlay(); }; function Tab(id){ this.oParent = document.getElementById(id); this.aInput = this.oParent.getElementsByTagName(‘input‘); this.aDiv = this.oParent.getElementsByTagName(‘div‘); this.iNow = 0; } Tab.prototype.init = function(){ var This = this; for(var i=0;i<this.aInput.length;i++){ this.aInput[i].index = i; this.aInput[i].onclick = function(){ This.change(this); }; } }; Tab.prototype.change = function(obj){ for(var i=0;i<this.aInput.length;i++){ this.aInput[i].className = ‘‘; this.aDiv[i].style.display = ‘none‘; } obj.className = ‘active‘; this.aDiv[obj.index].style.display = ‘block‘; }; Tab.prototype.autoPlay = function(){ var This = this; setInterval(function(){ if(This.iNow == This.aInput.length-1){ This.iNow = 0; } else{ This.iNow++; } for(var i=0;i<This.aInput.length;i++){ This.aInput[i].className = ‘‘; This.aDiv[i].style.display = ‘none‘; } This.aInput[This.iNow].className = ‘active‘; This.aDiv[This.iNow].style.display = ‘block‘; },2000); }; </script> 10、包裝對象 : JS基於原型的程序、系統對象也是基於原型的程序 盡量不要去修改或者添加系統對象下面的方法和屬性 基本類型都有自己對應的包裝對象 : String Number Boolean 基本類型會找到對應的包裝對象類型,然後包裝對象把所有的屬性和方法給了基本類型,然後包裝對象消失 var str = ‘hello‘; String.prototype.lastValue = function(){ return this.charAt(this.length-1); }; alert( str.lastValue() ); // o var str = ‘hello‘; str.number = 10; //創建對象後,包裝對象立即消失 alert( str.number ); //undefined 創建的新對象 11、原型鏈 原型鏈 : 實例對象與原型之間的連接,叫做原型鏈 原型鏈的最外層 : Object.prototype 對象調用的屬性在構造函數中沒有的話,會沿著原型鏈到該對象的prototype原型中查找,若還是沒有,則沿著最外層原型鏈到Object.prototype中查找 function Aaa(){ this.num = 10; // 優先級最高 } Aaa.prototype.num = 20; // 優先級第二 Object.prototype.num = 30; //優先級最後 var a1 = new Aaa(); alert(a1.num); 12、hasOwnProperty : 看是不是對象自身下面的屬性 var arr = []; arr.num = 10; Array.prototype.num2 = 20; alert( arr.hasOwnProperty(‘num‘) ); //true //只是arr中的屬性,其余的數組對象沒有 alert( arr.hasOwnProperty(‘num2‘) ); //false //數組對象原型中的屬性,所有數組都有這個屬性 alert( arr.hasOwnProperty == Object.prototype.hasOwnProperty ); //true // 這個屬性是在最外層的Object原型上 13、constructor : 查看對象的構造函數 function Aaa(){ } var a1 = new Aaa(); alert( a1.constructor ); //Aaa var arr = []; alert( arr.constructor == Array ); //true function Aaa(){ } Aaa.prototype.constructor = Aaa; //每一個函數都會有的,都是自動生成的 Aaa.prototype.constructor = Array; // 修改了對象的構造函數,避免這樣做 function Aaa(){ } Aaa.prototype.name = ‘小明‘; Aaa.prototype.age = 20; var a1 = new Aaa(); alert( a1.constructor ); //若用JSON形式寫Aaa的屬性,那麽a1的constructor不是Aaa了,而是JSON對象,即Object Aaa.prototype = { constructor : Aaa, name : ‘小明‘, age : 20 }; function Aaa(){ } Aaa.prototype.name = 10; Aaa.prototype.constructor = Aaa; for( var attr in Aaa.prototype ){ //遍歷不到JS內置屬性,只能遍歷到name alert(attr); } 14、instanceof : 對象與構造函數在原型鏈上是否有關系 //自定義對象 function Aaa(){ } var a1 = new Aaa(); alert( a1 instanceof Object ); //true //系統內置對象 var arr = []; alert( arr instanceof Array ); //true 15、toString() : toString() : 系統對象下面都是自帶的,不需要經過原型鏈尋。自己寫的對象都是通過原型鏈找Object下面的。 var arr = []; alert( arr.toString == Object.prototype.toString ); //false /function Aaa(){ } var a1 = new Aaa(); alert( a1.toString == Object.prototype.toString ); //true toString() : 把對象轉成字符串 var arr = [1,2,3]; Array.prototype.toString = function(){ return this.join(‘+‘); }; alert( arr.toString() ); //‘1+2+3‘ toString() : 進制轉換 var num = 255; alert( num.toString(16) ); //‘ff‘ //255轉成16進制 利用toString做類型的判斷 : (推薦) var arr = []; alert( Object.prototype.toString.call(arr) == ‘[object Array]‘ ); //‘[object Array]‘ 用constructor和instanceof判斷類型在iframe中判斷不出 alert( arr.constructor == Array ); //false alert( arr instanceof Array ); //false 16、繼承 繼承 :在原有對象的基礎上,略作修改,得到一個新的對象。不影響原有對象的功能。 子類不影響父類,子類可以繼承父類的一些功能 ( 代碼復用 ) 1)拷貝繼承: 屬性的繼承 : 調用父類的構造函數 call 方法的繼承 : for in : 拷貝繼承 (jquery也是采用拷貝繼承extend) function CreatePerson(name,sex){ //父類 this.name = name; this.sex = sex; } CreatePerson.prototype.showName = function(){ alert( this.name ); }; var p1 = new CreatePerson(‘小明‘,‘男‘); //p1.showName(); function CreateStar(name,sex,job){ //子類 CreatePerson.call(this,name,sex); //繼承 call改變this指向為對象 this.job = job; } //不能用對象的賦值,CreateStar.prototype = CreatePerson.prototype; 都指向同一內存地址,改變其中一個,另一個也會改變 extend( CreateStar.prototype , CreatePerson.prototype ); CreateStar.prototype.showJob = function(){ }; var p2 = new CreateStar(‘黃曉明‘,‘男‘,‘演員‘); p2.showName(); function extend(obj1,obj2){ //把父類所有的非對象屬性給子類 for(var attr in obj2){ obj1[attr] = obj2[attr]; } } 2)類式繼承: 類 : JS是沒有類的概念的 , 把JS中的構造函數看做的類 要做屬性和方法繼承的時候,要分開繼承,避免子類對象之間的修改相互影響屬性 屬性的繼承 : 調用父類的構造函數 call 方法的繼承 : 利用構造函數(類)繼承的方式 function Aaa(){ //父類 this.name = [1,2,3]; } Aaa.prototype.showName = function(){ alert( this.name ); }; function Bbb(){ //子類 ,屬性的繼承 Aaa.call(this); } //方法的繼承 var F = function(){}; F.prototype = Aaa.prototype; //只能繼承方法 Bbb.prototype = new F(); Bbb.prototype.constructor = Bbb; //修正指向問題 var b1 = new Bbb(); b1.name.push(4); alert( b1.name ); //[1,2,3,4] var b2 = new Bbb(); alert( b2.name );//[1,2,3] 3)原型繼承: 借助原型來實現對象繼承對象 var a = { name : ‘小明‘ }; var b = cloneObj(a); b.name = ‘小強‘; alert( b.name );//小強 alert( a.name );//小明 function cloneObj(obj){ var F = function(){}; F.prototype = obj; return new F(); } 拷貝繼承: 通用型的 有new或無new的時候都可以 類式繼承: new構造函數 原型繼承: 無new的對象 17、組件開發 : 多組對象,像兄弟之間的關系( 代碼復用的一種形式 ) 對面向對象的深入應用(UI組件,功能組件) 將 配置參數、方法、事件,三者進行分離 18、自定義事件 : 主要是跟函數有關系,就是讓函數能夠具備事件的某些特性 window.addEventListener(‘show‘,function(){ alert(1); },false); window.addEventListener(‘show‘,function(){ alert(2); },false); window.addEventListener(‘show‘,function(){ alert(3); },false); show(); //主動觸發自定義事件

JS筆記加強版3