JavaScript 基礎

1、JavaScript語言基礎(介紹js的基本語法)
一、全部的web開發永遠都是請求和響應。
二、javascript組成:
1)、核心語法(ECMAScript)  ECMA:歐洲計算機制造協會的簡稱
2)、Dom(文檔對象模型) document object model
3)、Bom(瀏覽器對象模型) browser object model
三、js簡介
1)、javascript是一種基於對象和事件的腳本語言,由瀏覽器來執行。
2)、能夠與用戶執行信息交互
3)、安全性,不容許訪問本地磁盤
4)、跨平臺,只要瀏覽器支持js就能夠
四、js代碼必須寫在<script></script>標籤內,
js裏面推薦字符串都用單引號'',
html和css屬性使用雙引號""。
五、彈出警告框:alert()
六、整個js代碼從上到下依次執行。用雙斜槓//來註釋js代碼。
七、當某個<script>標籤內有語法錯誤的時候,該<script>塊中的代碼都不執行,
可是不影響其餘<script>塊中的代碼執行。
八、鏈入一個外部js文件:
先建立一個js文件1.js,而後在html網頁中加<script src="1.js" type="text/javascript"></script>
九、聲明變量的時候不須要聲明數據類型,統一使用var來聲明變量。js是一種弱類型語言。
聲明一個變量,給其賦值多種類型的值是合法的。例如:var a=10;a=false;a=sdsfsfsf;
十、以字母、下劃線或$開頭,中間能夠包括字母、數字、下劃線或$
十一、數據類型:Bollean(布爾)、Number(數字)、String(字符串)、Undefined(未定義)、Null(空對象)、Object(對象類型)
十二、typeof() 返回的是變量的數據類型
1三、if-else、while、do-while、for、switch、continue、break語句與C#差很少
1)、聲明變量後,使用前必定要賦初值,不然變量就是undefined。
var sum=0;
for(var i=1;i<=100;i++){
    sum+=i;
}
alert(sum);
2)、當使用一個未聲明的變量時,瀏覽器會報錯。
3)、方法沒有返回值的時候,接收到的返回值是undefined
4)、不管變量是undefined仍是null都表示該變量不可用
判斷變量是否可用:
if(typeof(x)!='undefined'&&x!=null){變量可用}else{變量不可用}
1四、相等:==,先判斷數據類型是否同樣,若是不同,經過數據轉換可以轉成相同的值,則返回相等
1)、若是==兩邊都是字符串類型,那麼必須這兩個字符串徹底相同纔會返回true
2)、若是==兩邊的兩個變量指向了同一個對象,那麼也返回true
3)、若是==兩邊一個是字符串類型,一個是數字類型,那麼js引擎會嘗試把其中的字符串類型嘗試轉換爲數字類型後再作比較
4)、若是==兩邊一個是布爾類型,一個是數字類型,則也會嘗試把其中的布爾類型嘗試轉爲數字類型後再作比較
5)、若是==兩邊其中一個是string或者number類型,而另一個object類型,那麼判斷相等以前會先講object轉換爲string或number後而後在與另一個值比較
1五、徹底相等:===,直接進行比較,不作數據轉換。相等就是相等,不相等就是不相等。
alert(sum);
var n1='123';
var n2=123;
alert(n1==n2);  //true
alert(n1===n2);  //false
var n1=null;
var n2;
alert(n1==n2);     //true
alert(n1===n2);    //false
undefined==udenfined  //true
null==null //true
NaN==NaN //fales
null==undefined  //true
new String("a")=="a" 返回結果是true,而new String("a")==new String("a")是false
1六、變量的做用域:
1)、js中不存在塊級做用域範圍,在頁面中聲明的變量,在整個頁面中的任何一個地方都可以使用
2)、在方法內部任何一個地方聲明的變量的做用域爲整個方法內部,即在方法內部任何地方均可以使用該變量
3)、當重複聲明變量的時候,js會自動忽略第一次之後的全部聲明語句,可是賦值語句正常執行。
4)、聲明變量的時候若是不寫var關鍵字,表示該變量是一個整個頁面均可以訪問的變量(全局變量)
1七、轉義符:'\'
alert('姓名:小紅\r\n 年齡:20')
1八、數據類型轉換:
1)、字符串轉化爲數字,從給定字符串中找到第一個不能轉化爲數字的字符串,將其以前的字符串轉化爲數字
var n='123';
n=parseInt(n);
alert(n+1);//124
var n='123sssdafg';
n=parseInt(n);
alert(n+1);//124
var n='15';
n=parseInt(n,8);   //把'15'按八進制轉化爲數字爲13
alert(n);//13
2)、把任意類型轉化位數字
Number('fales')=0;
Number('true')=1;
Number('undefined')=NaN;
Number('null')=0;
Number('new object()')=NaN;
3)、把任意類型轉化爲布爾類型
Boolean("")=false;
Boolean("Hi")=true;
Boolean(5)=true;
Boolean(null)=false;
Boolean(0)=fales;
Boolean(new object())=true;
Boolean(NaN)=false;
4)、把任意類型轉換會String類型
var n=123;
n.toString();//"123"
String(n);//"123"   
var n=null;
n.toString();//報錯,null對象不能點出來toString()方法,不能調用任何方法
String(n);//"null"  經過該方法能夠獲得null對象就是一個null值,能夠把任何類型的數據轉換爲string類型javascript

1九、判斷字符串是否是NaN只能用IsNaN()來判斷,不能用n==NaN來判斷
20、eval():把字符串看成js代碼來解析執行。能夠用於拼接代碼。不安全。
var n='var x=1;x++;alert(x);';
eval(n);  //2
x++;
alert(x);  //3
2一、邏輯運算符:與C#中邏輯運算符多出來的功能就是可以直接將判斷結果賦值給變量。
&& 邏輯與
|| 邏輯或
var r="a"||"";
alert(r); //a   邏輯或,第一個爲真,第二個就不用判斷了直接返回第一個爲真的值
r=null ||15;
alert(r); //15  邏輯或,第一個爲假,再判斷第二個,若是第二個爲真則返回第二個爲真的值
r="a" && 0;
alert(r); //0   邏輯與,第一個爲真,再判斷第二個,若是第二個爲假則返回第二個爲假的值
r=null && 15;
alert(r); //null 邏輯與,第一個爲假,第二個就不用判斷了,直接返回第一個爲假的值
r="12123" || 12;
alert(r); //12123 邏輯或,第一個爲真,第二個就不用判斷了直接返回第一個爲真的值
r="12123" && 12;
alert(r); //12    邏輯與,第一個爲真,第二個也爲真,直接返回最近的第二個爲真的值
2二、調試:程序若是有錯,按F12打開開發人員工具,點控制檯console就能看到錯誤信息。
 單步調試:打開開發人員工具,而後點調試器,開始調試,在須要調試的代碼前面設置斷點,而後再網頁上刷新一下,程序就會運行到斷點的位置,
 選中要監視的變量,右鍵菜單選擇添加監視,而後按F11單步調試,在監視窗口能夠看到變量的值的變化狀況。css

調試的時候須要注意:1)、瀏覽器不能禁用js 2)、實在不能調嘗試將瀏覽器的各類插件卸載清空重啓一下 3)、同時只能使用用個調試器調試(不要幾個瀏覽器或vs同時用)html

2三、函數:
命名規則:駝峯,首字母小寫,以後的首字母大寫。
//定義一個函數
function sayHi(){
    alert('Hi');
}
//調用一個函數
sayHi();java

2四、函數重載:在js中沒有函數重載
由於js中沒有函數重載的概念,因此遇到同名函數的時候,會用最後一次定義的函數覆蓋前面的函數定義。
下面例子調用的是第二個sayHi()。
            //定義一個函數
            function sayHi(){
                alert('Hi');
            }
            //再定義一個同名函數
            function sayHi(name){
                alert(name);
            }
            //調用一個函數,此處調用的是sayHi(name)函數,返回結果爲undifined
            sayHi();
全部的方法都無需定義形參,定義形參的目的是爲了使用方便,不管是否認義了形參,在實際調用的時候,全部參數都包含在arguements對象中。
        function add(){
            var sum=0;
            for(var i=0;i<arguments.length;i++){
                sum+=arguments[i];
            }
                return sum;
            }
            var result= add(1,1);
            alert(result);
由於函數有預解析(在同一個標籤內)的功能,因此在執行以前會將全部的函數進行預解析。在預解析的時候會使用最後定義的函數覆蓋前面定義的重名函數。
var x=1,y=0,z=0;
            function add(n){n=n+1;return n;}
            y=add(x);  //結果是4,由於預解析的時候最後定義的函數覆蓋了前面定義的函數,這裏調用的是最後定義的函數
            function add(n){n=n+3;return n;}
            z=add(x);  //結果是4
            
當函數內部聲明的變量與外部聲明的變量重名時優先使用內部聲明的變量
            var uname='000';
            function getName(){
                alert(uname);     //undefined  變量也有預解析,這裏已經知道函數內部聲明瞭一個uname變量,只能預解析聲明,不能預解析賦值,因此這裏的uname變量是一個未賦值的,執行的時候就會返回undefined
                var uname="111";
                alert(uname);     //111   直接返回賦值的值
            }
            getName();
            alert(uname);          //000   函數內部的變量做用域只能在函數內部,這裏是調用的最前面聲明的變量web

2五、函數能夠被看成函數來調用,也是一個對象,具備對象的基本方法。
   function myFunction(){
                for(var i=0;i<10;i++){
                    alert(i);
                }
            }
            myFunction(); //函數調用
            alert(myFunction.toString());//將函數看成字符串打印出來,返回函數的源代碼
            alert(myFunction.length);//函數定義的形參個數
            
            var f1=function (){alert('這是一個匿名函數');};  //把函數賦值給了一個變量
            f1();    //調用匿名函數
            f1=100;    
            alert(f1);
            f1=function (x,y) {return x+y;};  //把一個有形參的匿名函數賦值給變量
            var r=f1(10,20);   //調用有形參的匿名函數
            alert(r);
            //將一個函數看成另一個函數的形參
            function f1 (fn) {
                alert('這是f1函數');
                fn();
            }
            f1(function () {alert('直接傳遞的匿名函數');})  //將一個匿名函數看成形參傳入另外一個函數
            f1(f12);   //講一個函數看成形參傳給另外一個函數
            function f12() {
                alert('12');
            }
            (function (x,y) {alert(x+y);})(10,20);//定義匿名函數的同時直接調用匿名函數正則表達式

經過new Function()的方式定義匿名函數,能夠將函數代碼用字符串來表示,同時在函數中使用的變量,不會做爲頁面的全局變量出現,在函數外部也訪問不到
            var f1=new Function('x','y','z','alert(x+y+z);');
            f1(10,20,30);json

匿名函數不具有預解析功能
            var x=1,y=0,z=0;
            var add=function (n){n=n+1;return n;}
            y=add(x);  //結果是2,由於匿名函數不具有預解析功能,在這裏至關於一個賦值語句,遵循從上到下的執行邏輯
            var add=function (n){n=n+3;return n;}
            z=add(x);  //結果是4數組

2六、數組:數組也能夠做爲另一個數組的元素 var data=[1,2,3,[4,5,6]];  這個數組的長度是4
            //申明一個數組,這種寫法叫作數組字面量
            var numbers=[1,2,3,4,5];  //申明數組的時候同時初始化
            alert(numbers.length); //數組長度
            //循環遍歷數組
            for(var i=0;i<numbers.length;i++){
                alert(numbers[i]);
            }
            //當調用數組對象的ToString()方法,會返回一個由逗號隔開的數組字符串
            alert(numbers.toString());
            //申明一個空數組
            var data=[];
            //將1-50之間的全部偶數放到data數組中
            for(var i=1;i<=50;i++){
                if(i%2==0){
                    data[data.length]=i;
                }
            }
            alert(data.toString());瀏覽器

            //清空數組,給數組賦值一個空數組或者讓其長度爲0安全

           data=[];

           data.length=0;
            //數組的其餘申明方式
          var arr=new Arry(); //申明空數組
            var arr=new Arry(1,2,3); //插入一個長度爲3包含三個元素的數組

     var arr=new Arry(5);//申明一個長度爲5的數組

    //將一個數組按從大到小順序排序

            var data=[9,1,2,5,4,6,7,3,8];//聲明一個無序數組
            fnSortArray(data);  //調用排序的函數
            alert(data.toString()); //彈出數組字符串

    //定義一個函數,其功能是使用冒泡排序將無序數組按從大到小順序排序
            function fnSortArray(arrayObject){
                var tmp,i,j;
                for(var i=0;i<arrayObject.length;i++){
                    for(var j=arrayObject.length-1;j>i;j--){
                        if(arrayObject[j]>arrayObject[j-1]){
                            tmp=arrayObject[j];
                            arrayObject[j]=arrayObject[j-1];
                            arrayObject[j-1]=tmp;
                        }
                    }
                }
            }

            //計算整數數組中的平均值
            var data=[9,1,2,5,4,6,7,3,8];
            var result= fnAverage(data);
            alert(result);
            function fnAverage(arrayObject){
                var sum=0,i;
                for(i=0;i<arrayObject.length;i++){
                    sum+=arrayObject[i];
                }
                return sum * 1.0/arrayObject.length;
            }

            //求一個數組中的最大值
            var data=[9,1,2,5,4,6,7,3,8];
            var result=fnMax(data);
            alert(result);
            function fnMax(arrayObject){
                var max=arrayObject[0],i=1;
                for(;i<arrayObject.length;i++){
                    if(arrayObject[i]>max){
                        max=arrayObject[i];
                    }
                }
                return max;
            }

           //將一個字符串數組['張三','李四','王五']輸出以「|」分割的字符串
            var arr=['張三','李四','王五'];
            //var result=arr.join('|');   //調用js內置的join函數

            var result=fnJoin(arr,'|')
            alert(result);
            //本身定義一個相似join的函數
            //一、遍歷數組中的每一個元素 二、使用指定的分割符來拼接字符串
            function fnJoin(arr,separator){
                var str="",i;
                for(i=0;i<arr.length-1;i++){
                    str=str+arr[i]+'|';
                }
                str=str+arr[arr.length-1];       //最後一個單獨拿出來最後再拼接
            }

           //將一個數組中的元素進行先後反轉
            var data=[9,1,2,5,4,6,7,3,8];
            //data.reverse();    //調用js內部的翻轉函數
            fnReverse(data);
            alert(data);
            function fnReverse(data){
                var tmp,i;
                for(i=0;i<data.length/2;i++){
                    tmp=data[i];
                    data[i]=data[data.length-1-i];
                    data[data.length-1-i]=tmp;
                }
            }

2七、數組相關方法:詳見http://www.w3school.com.cn/jsref/jsref_obj_array.asp

toString()方法:將數組元素以字符串形式打印出來

join()方法:把數組的全部元素放入一個字符串。元素經過指定的分隔符進行分隔

reverse()方法:將數組元素先後反轉

concat()方法:鏈接兩個或更多的數組,並返回結果 。兩個數組鏈接的長度等於兩個數組長度的和。

                 var str1=['張三','李四','王五'];

                 var str2=['張三1','李四1','王五1',['ZS','LS','WW']];

                 var result=str1.concat(str2);//返回的結果是['張三','李四','王五','張三1','李四1','王五1',['ZS','LS','WW']]。打印出來看起來長度是9,實際上長度爲7。

sort()方法:對數組的元素進行排序,sort()方法只能按從大到小從前到後得順序排序(順序),不能進行倒序,若是想要倒着排序,能夠先調用數組sort()方法,以後再調用數組reverse()方法

                 sort()方法排序默認是將數組元素看成字符串來排序的,例如:var num=[2,1,11,23,3,34,4,45];

                                                                                               num.sort();

                                                                                               alert(num); //返回結果爲:1,11,2,23,3,34,4,45

                                                                                                //若是想要將數組元素看成數字來排序,須要以下調用

                                                                                                num.sort(function (x,y){return x-y;}); //從小到大排

                                                                                                //num.sort(function (x,y){return y-x;}); //從大到小排

                                                                                                 alert(num);//結果爲:1,2,3,4,11,23,34,45

                 以上例子爲元素爲數字的數組,若是是元素爲字符串的數組,能夠按照字符串的長度來排序,匿名函數應該這麼寫:function (x,y){return x.length-y.length;}

                 爲何要在調用的時候傳一個匿名函數呢?如下用代碼來解釋,此處模擬了sort()內部的實現原理

                 //定義一個函數(利用冒泡排序),這個函數的功能就是對數組進行升序排序,將比較兩個元素的過程進行封裝,由於不能肯定要比較的元素是數字仍是字符串

                //由於數組是引用類型,因此不須要設置返回值,函數裏面數組值改變,外面跟着也變了 -->
                function fnSortAsc(arrayObject,fn){
                var tmp,i,j;
                    for(var i=0;i<arrayObject.length-1;i++){
                        for(var j=arrayObject.length-1;j>i;j--){
                            if(fn(arrayObject[j],arrayObject[j-1])<0){
                                tmp=arrayObject[j];
                                arrayObject[j]=arrayObject[j-1];
                                arrayObject[j-1]=tmp;
                            }
                        }
                    }
                }

               //定義一個比較數字的函數
                function fnCompareTwoValues(obj1,obj2){
                    //若是Obj1大於obj2則返回一個大於0的值,若是obj1小於obj2返回小於0,若是相等則返回0
                    return obj1-obj2;
                }
                var data=[2,1,4,3,6,5];
                fnSortAsc(data,fnCompareTwoValues);
                alert(data);
                var arrName=['BigSkyDog','EatMoodChildSon','DrinkBeerChildSon','apple'];

               //定義一個比較字符串長度的函數
                fnSortAsc(arrName,function (x,y){
                    return x.length-y.length;
                })
                alert(arrName);

push()方法:向數組的末尾添加一個或更多元素,並返回新的長度

pop()方法:刪除並返回數組的最後一個元素,即將數組得最後一個元素刪除,而後再返回

shift()方法:刪除並返回數組的第一個元素,即將數組的第一個元素刪除,而後再返回

unshift()方法:向數組的開頭添加一個或更多元素,並返回新的長度

slice()方法:從某個已有的數組返回選定的元素

splice()方法:刪除元素,並向數組添加新元素

valueof()方法:返回數組對象的原始值

2八、鍵值對數組(常說的json格式):鍵爲數字的數組是一個特殊的鍵值對數組,數組均可以用for-in循環來遍歷

                 var dict=new Array();
                 dict['dtg']='大天狗';
                 dict['cmtz']='茨木童子';
                 dict['jttz']='酒吞童子';    
                  //根據鍵查找值
                 alert(dict['dtg']);
                 //打印數組的長度
                 alert(dict.length); //返回結果爲0,由於數組長度只統計鍵爲數字的元素
                 //若是要遍歷鍵值對數組,由於數組長度爲0,不能用for()循環方式,因此這時候能夠用for-in循環(相似於C#中的foreach循環)
                 for(var key in dict){
                    alert('鍵:'+key+'     值是:'+dict[key]);
                 }

鍵值對數字也有一個簡單的寫法(對象字面量):

       var dict={'dtg':'大天狗','cmtz':'茨木童子','jtz':'酒吞童子'};

由於是對象字面量,因此 除了用dict['dtg']的方式能取到值'大天狗',還能夠用dict.dtg的方式取值,同時也能夠用dict.ydj='妖刀姬'的方式向鍵值對數組中新增元素。

如下都是正確的鍵值對數組的格式:

var arr={'dtg':'大天狗','cmtz':'茨木童子','jtz':'酒吞童子'};  //總體是個鍵值對集合

var arr=[{'dtg':'大天狗','cmtz':'茨木童子','jtz':'酒吞童子'},{'dtg':'大天狗','cmtz':'茨木童子','jtz':'酒吞童子'}];//總體是一個數組,而後裏面的每一個元素又是鍵值對集合var arr={'dtg':'大天狗','cmtz':'茨木童子','jtz':'酒吞童子','yys':{'dtg':'大天狗','cmtz':'茨木童子','jtz':'酒吞童子'}};//總體是一個鍵值對集合,最後一個鍵的值又是一個鍵值對集合

2九、字符串:

length屬性:獲取字符串的字符個數,無論是中文字符仍是英文字符都算做一個字符。

                var msg='你好js';alert(msg.length);//返回長度爲4

charAt()方法:獲取指定索引位置的字符

               var msg='你好js';alert(msg.charAt(1));//返回字符爲‘好’

indexOf()方法:獲取指定字符在字符串中第一次出現的位置

     var msg='我爲人人,人人爲我';alert(msg.indexof('我'));//返回位置爲0

          alert(msg.indexof('我',2));//返回位置爲8,參數2爲從位置爲2的地方開始找第一次出現元素‘我’的位置爲8

              循環找出字符串中的某個字符的位置:

                 var msg='我爲人人,人人爲我,人人爲我,人人爲我,人人爲我';
                 var index=0,count=0,keywords='人人';
                  while((index=msg.indexOf(keywords,index))!=-1){
                    count++;
                    alert('第' + count+'次出現「人人」的索引的位置是:'+index);
                    index=index+keywords.length;
                  }

substr()與substring()方法:

      var msg='我爲人人,人人爲我';
                  msg=msg.substr(0,4);   //從第0個元素開始截取4個字符
                  alert(msg);  //返回‘我爲人人’

                  var msg='我爲人人,人人爲我';
                  msg=msg.substr(5);   //從第5個元素開始截取到最後
                  alert(msg);  //返回‘人人爲我’

                  var msg='我爲人人,人人爲我';
                  msg=msg.substring(5,8);  從第5個元素位置開始截取到第8個元素位置爲止(不包含第8個位置的元素)
                  alert(msg);//返回‘人人爲’

                 練習:去掉字符最後的‘|’

                  var msg='大天狗|茨木童子|酒吞童子|';
                  //msg=msg.substr(0,msg.length-1); //用substr()從第0個元素位置開始向後截取13個元素
                  msg=msg.substring(0,msg.length-1);//用substring()從第0個位置截取到位置13的元素爲止(不包含位置爲13的元素)
                  alert(msg);

toUpperCase()方法:將小寫都轉換成大寫

toLowerCase()方法:將大寫都轉換成小寫

split()方法:根據分隔符返回一個字符串數組,分隔符必需要有,不帶參數的話就是返回所有元素,參數是幾返回幾個元素,若是所填參數大於實際元素個數也是返回實際最大個數

                  不帶參數:

                  var msg='大天狗|茨木童子|酒吞童子';
                  var arr=msg.split('|');   //以‘|’爲分割符分割字符串
                  alert(arr);
                  alert(arr.length);

                 帶參數:

                  var msg='大天狗|茨木童子|酒吞童子';
                  var arr=msg.split('|',2);   //以‘|’爲分割符分割字符串,而且只返回2個元素
                  alert(arr);
                  alert(arr.length);

                  分割符用正則表達式:

                  var msg='大天狗|茨木童子%酒吞童子@妖刀姬&姑獲鳥';
                  var arr=msg.split(/\||%|@|&/);   //以‘|’或者‘%’或者‘@’或者‘&’爲分割符分割字符串
                  alert(arr);
                  alert(arr.length);

30、日期:   var d=new Date();//聲明一個日期對象
                  console.log(d.getDate());//獲取當前是幾號
                  console.log(d.getFullYear());//獲取當前是哪一年
                  console.log(d.getMonth());//獲取當前是第幾個月,默認第0個月爲1月,第1個月爲2月,依此類推。。。第11個月爲12月
                  console.log(d.getDay());//獲取當前是周幾
                  console.log(d.getHours());//獲取當前是幾點
                  console.log(d.getMinutes());//獲取當前分鐘
                  console.log(d.getSeconds());//獲取當前秒
                  console.log(d.getTime());//獲取從1970年1月1號到當前時間的秒數

3一、JS中的對象

                  //這是一個函數,也可稱爲「函數對象」,建立函數的時候若是要看成「構造函數」用則首字母大寫,若是是看成函數用首字母小寫。
                  function Person(){
                    
                  }
                  //對Person()函數能夠直接調用,即:直接把Person()當作函數來使用
                  Person();//把Person()看成普通函數來適用
                  //把Person()函數看成「類」來使用,經過Person()函數來建立一個Person()類型P
                  //當調用Person函數的時候在前面加關鍵字new,表示要經過Person()函數建立一個對象,此時把Person()函數叫作「構造函數」(不是「類」)
                  var p=new Person();//建立一個Person類型的對象P
                  //添加屬性並賦值
                  p.user_name='lp';
                  p.age='20';
                  p.email='lp@163.com';
                  //建立一個方法
                  p.sayHi=function(){
                    
                  };
                  p.sayHi();//調用方法
                  
                  //經過構造函數建立Person對象,只有給this關鍵字建立成員屬性,之後建立該對象的時候才能調用到成員屬性
                  function Person(name,age,email){
                    this.user_name=name;
                    this.user_age=age;
                    this.user_email=email;
                    this.sayHello=function(){
                        
                    };
                  }
                  //建立對象
                  var p1=new Person('lp',20,'lp@163.com');
                  p1.sayHello();//調用方法

                  //對象也能夠看做是鍵值對集合,能夠遍歷
                  for(var key in p1){
                    alert(key+'    '+p1[key]);
                  }

                 //判斷一個對象是不是Person類型,適用instanceof關鍵字,相似於C#中的is關鍵字(p1 is Person)
                  alert(p1 instanceof Person);
                  alert(p1 instanceof Object);

                 //經過對象字面量來直接建立對象,能夠快速的封裝數據
                  var p1={
                    user_name:'lx',
                    user_age:19,
                    say_hi:function(){
                        alert('你們好我叫:'+this.user_name);
                    },
                    say_hello:function(){alert('個人年齡是:'+this.user_age);}
                  };
                  p1.say_hi();
                  p1.say_hello();

3二、函數對象中的prototype屬性:原型
                  //每次建立一個對象都是一個徹底獨立的對象,對象與對象之間沒有關係,新對象調用方法的時候調用的是新對象本身的方法,由於建立新對象的時候不只僅是給對象變量賦值,同時也建立了新對象本身的方法。好處就是新對象與新對象之間互不影響,弊端每建立一個對象都會建立一個重複的方法,而方法函數是一個引用類型,過多的重複方法會佔用存儲空間形成存儲資源的浪費。
                  function Person(name,age){
                    this.user_name=name;
                    this.user_age=age;
                    this.say_hi=function(){
                        alert('我叫  '+this.user_name+'  我今年  '+this.user_age+' 歲了!');
                    };
                  }
                  var  p1=new Person('tj',24);
                  var  p2=new Person('jj',22);
                  p1.say_hi();
                  p2.say_hi();

                  function Person(name,age){
                    this.user_name=name;
                    this.user_age=age;
                  }
                  //將對象的方法經過對象的prototype屬性建立,這樣new一個對象的時候,新對象只用給對象的變量賦值,調用方法的時候調用的就不是新對象的方法,而是全部Person類型的方法,這樣能夠節約存儲資源。

                  //函數對象Person自己是不具有name,age屬性的,而經過new Person()的新對象才具備name,age屬性

                 //prototype屬性是函數對象Person的,下面經過Person建立的p1,p2普通對象沒有prototype屬性,在這裏Person對象就叫作原型對象

                 //在原型對象Person的prototype中加一個sayHi方法,想要往原型對象中加方法能夠往原型對象的prototype中加。
                  Person.prototype.sayHi=function(){
                        alert('我叫  '+this.user_name+'  我今年  '+this.user_age+' 歲了!');
                  };
                  var  p1=new Person('tj',24);
                  var  p2=new Person('jj',22);
                  p1.sayHi();  //爲何在建立對象p1,p2的時候並無prototype屬性,可是又能夠調用prototype中的sayHi方法呢,由於在建立p1,p2的時候雖然沒有建立prototype可是建立了一個字段__proto__ ,而這個字段的做用就是讓對象p1,p2指向原型對象Person的prototype,這樣就能調用方法了。

                 //在prototype中也有一個__proto__字段,做用和上面同樣。 若是在prototype中沒有找到要調用的方法,這時候程序就會經過prototype的__proto__字段往它的上一層或上上一層找,最後找到了就調用成功,找到object對象也沒找到就會報錯。
                  p2.sayHi();

------------------------------------------------------------------------------------------------------------------------

            //原型對象中的成員是隻讀的
            function Person(name){
                this.user_name=name;
            }
            Person.prototype.user_age=20;
            Person.prototype.friends=['張三','李四']
            Person.prototype.sayHi=function(){
                alert('你們好我叫:'+this.user_name+'   我今年:'+this.user_age);
            };
            var p1=new Person('田七');
            p1.user_age=19;//這裏是給p1對象添加了一個user_age屬性而且賦值,這裏的賦值對原型對象中的user_age沒有影響,由於原型對象中的成員是隻讀的,不能修改值,這裏是值類型的成員(字符串,數字都是值類型)
            p1.sayHi(); //這裏打印出來的田七的年齡是19
            var p2=new Person('王八');
            p2.sayHi();//這裏打印出來王八的年齡是20,由於原型對象中的成員只讀

           ---------------------------------------------------------------------
            var p1=new Person('田七');
            p1.friends[0]='王五'; //這裏friends是一個數組,爲引用類型,在原型對象(能夠看做是棧)中成員爲一個地址,而這裏修改的內容是地址對應的存儲器(堆)中的內容,因此說變的不是成員而是成員地址指向的一塊內容。

            alert(p1.friends);//這裏打印出來的是王5、李四。由於原型對象中friends成員指向的內容已經被p1對象改變了,因此這裏p2再調用這個成員也發生改變。
            var p2=new Person('王八');

            alert(p2.friends);//這裏打印的是王五,李四

            --------------------------------------------------------------------------

           var p1=new Person('田七');
            p1.friends=['王五','李四'];//這裏和前面age的緣由同樣,程序想改原型對象中的friends成員,可是原型對象中的成員不可變,因而程序就給p1對象新加了一個屬於p1對象的friends屬性,這裏的賦值對原型對象中的friends成員沒有影響。
            alert(p1.friends);//這裏打印出來的是王5、李四。
            var p2=new Person('王八');
            alert(p2.friends);//這裏打印的是張三,李四。由於p1對象的賦值對原型對象成員friends無影響,因此p2調用原型對象的friends也無變化。

           //經過原型能夠實現擴展方法的功能,最好只擴展本身寫的方法,不要去給系統方法添加原型成員(String等)

          //下面這樣寫,語法沒錯,可是不建議給系統方法添加原型成員,由於這樣容易引發系統混亂(註冊的方法多了,又嚴格區分大小寫,很差區分)

            var msg='abcdefghijklmn';
            String.prototype.addHHH=function(){
                return this+'HHH'
            };
            msg=msg.addHHH();
            alert(msg);

3三、JS中的繼承:下面例子中Student對象繼承自Person對象,Person對象繼承自Object,Object繼承自null。

                  //一、在js中沒有類的概念,繼承是經過對象和對象來實現的。
                  function Person(name,age){
                    this.user_name=name;
                    this.user_age=age;
                  }
                  Person.prototype.sayHi=function(){
                        alert('我叫  '+this.user_name+'  我今年  '+this.user_age+' 歲了!');
                  };
                  function Student(sid){
                    this.student_id=sid;
                  }
                  var p1=new Person('張三',18);
                  //繼承
                  Student.prototype=p1;
                  var s1=new Student('10001');
                  //s1.sayHi();
                  //要修改s1的屬性值能夠直接改
                  s1.user_name='王五';
                  s1.user_age=20;
                  s1.sayHi=function(){
                    alert('我叫  '+this.user_name+'  id是: '+this.student_id+'  我今年  '+this.user_age+' 歲了');
                  };
                  s1.sayHi();

3四、閉包:實際上就是經過做用域鏈來改變變量的做用域,JS中的面向對象都是用‘閉包’來模擬的

          function Person(name){
                    this.user_name=name;
                    var user_age=18;
                  }
                  var p1=new Person('lgz');
                  alert(p1.user_name);
                  alert(p1.user_age);//這裏是undefined,由於上面Person對象沒有把user_age註冊給this,也就是這裏的p1。而在此處調用p1.user_age至關於給p1註冊了一個user_age,可是又沒有賦值,因此打印出來就是undefined

                  --------------------------------------------------

                  function Person(name){
                    this.user_name=name;
                    var user_age=18;
                    this.setAge=function(age){
                        user_age=age;
                    };
                    this.getAge=function(){
                        return user_age;
                    };
                  }
                  var p1=new Person('lgz');
                  //在上面Person對象中註冊了相似於C#中給私有字段添加屬性的過程,就可經過下面的方式訪問到user_age成員了
                  p1.setAge(20);
                  alert(p1.getAge());

-------------------------------------------------------------------------------

                  function f1(){
                    var funs=new Array();
                    
                    for(var i=0;i<10;i++){
                        funs[i]=function(){
                            alert(i);
                        };
                    }
                    return funs;
                  }
                  var myFuns=f1();
                  //下面打印結果是10次10
                  for(var n=0;n<myFuns.length;n++){
                    myFuns[n]();
                  }
                  //爲何上面會打印出10個10,而不是0到9呢?

                 //f1()中返回的是一個函數數組funs(數組中存儲了10個alert(i)),接着又將f1()賦值給myFuns,myFuns也就是一個函數數組(數組中存儲了10個alert(i)),當循環遍歷myFuns的時候,調用myFuns[n]()會循環執行數組中的每個alert(i),而在調用myFuns[n]()的時候f1()中的for()循環早就已經循環完畢了,這個時候i的值已經爲10,因此說無論後面n爲幾,alert(i)的結果一直都爲10。

3五、函數中的this:1)、在一個函數內部this指的是哪一個對象,取決於當前函數是哪一個對象的函數。當函數註冊給不一樣的對象時,函數內部的this不會一直爲某個對象而是會隨函數所屬的變化而變化。

                          2)、若是將函數

                  //下面的f1()中的this實際上就是window對象

                  function f1(){
                    alert(this);
                  }
                  f1();//打印結果爲window,由於在頁面上定義的函數默認就是註冊給window對象,因此直接f1()調用函數和window.f1()這樣調用是徹底同樣的。

                 --------------------------------------------------

                 var name='window中的name';
                  function Person(){
                    this.name='Person中的name';
                    this.getName=function(){
                        return function(){
                            return this.name;
                        };
                    };
                  }
                  var p=new Person();
                  alert(p.getName()());//這裏打印出來的是window中name。由於Person對象中return function(){}並無註冊給this.getName,因此return function(){}中的name指的就是window.name

                  -----------------------------------------------------------

                  //若是想要打印出Person中的name,須要像以下 這樣寫

                  var name='window中的name';
                  function Person(){
                    this.name='Person中的name';
                    this.getName=function(){
                        alert(this.name);
                    };
                  }
                  var p=new Person();
                  alert(p.getName()());

                  //或者這樣寫

       function Person(){
                    this.name='Person中的name';

                    //先將表明Person對象的this賦給that,再return that.name就能夠了,這裏的that就是Person對象
                    this.getName=function(){
                        var that=this;               
                        return function(){
                            return that.name;
                        };
                    };
                  }
                  var p=new Person();
                  alert(p.getName()());

3六、js編寫事件:

    <body>        <input onclick="alert(new Date().toLocaleTimeString());" type="button" name="name" value="顯示當前時間"/>        <a onclick="alert('hello');" href="http://www.baidu.com">百度</a>                      //單擊超連接以後彈出hello,頁面跳轉至百度,將js代碼寫到onclick事件        <a onclick="alert('hello');return false;" href="http://www.baidu.com">百度</a>    //單擊超連接以後彈出hello,頁面不跳轉,將js代碼寫到onclick事件        <a  href="javascript:alert('hello');">百度</a>                                                    //單擊超連接以後彈出hello,將js代碼直接寫到href裏,其中javascript:是一種解析js代碼的協議    </body>

相關文章
相關標籤/搜索