讀書筆記-JavaScript面向對象編程(一)

前先後後大概花了兩週的時間,終於把這本書大體看完了,對以前javascript高級程序設計中模糊不清的概念,有了一些新的見解和角度,總體上來講,本書仍是一本比較適合有必定前端基礎的朋友們閱讀。參考http://pan.baidu.com/s/1eSDSTVW 密碼: 75jrjavascript

第1章 引言前端

1.1 回顧歷史java

1.2 變革之風正則表達式

1.3 分析現狀數組

1.4 展望將來瀏覽器

1.5 面向對象的程序設計閉包

  1.5.1 對象(屬性和方法的集合)app

  1.5.2 類 (類似對象的共同特徵,如麻雀、老鷹都是鳥類)dom

  1.5.3 封裝 (將屬性和方法集合起來,也有封閉做用域的概念,如封裝一個播放器對象)函數

  1.5.4 聚合 (將幾個對象合併成一個對象)

  1.5.5 繼承 (一個實例對象繼承父級對象的一些屬性和方法)

  1.5.6 多態 (一個對象調用其餘對象的方法,call和apply)

1.6 OPP概述

1.7 訓練環境設置

1.8 使用Firebug控制檯

1.9 本章小結

 

第2章 基本數據類型、數組、循環及條件表達式

2.1 變量 (命名規則、聲明前置、做用域)

2.2 操做符 (+、-、*、/、%、++、--、=、+=、-=、*=、/=、%=)

2.3 基本數據類型 (數字、字符串、布爾值、undefined、null)

  2.3.1 查看類型操做符 typeof

  2.3.2 數字(整數或浮點數,typeof返回number,八進制0開頭,十六進制0x開頭,指數表示法1e+1=10,2e-3=0.002)

       (Infinity無窮大不可運算,typeof NaN也是number,NaN具備傳染性即帶入運算結果爲NaN)

  2.3.3 字符串(單雙引號之間的任何值,typeof返回string,*1或parseInt轉換爲數字)

        (\轉義字符,\n換行符,\r回車符,\t製表符,\u後面爲Unicode碼)

  2.3.4 布爾值(typeof返回boolean,邏輯運算符!、&&、||會默認轉換,6個falsy["",null,undefined,0,NaN,false])

        (比較運算符==、===、!=、!==、>、>=、<、<=,NaN不等於任何包括本身)

  2.3.5 undefined和null(不存在或未賦值的變量時獲得undefined,null須要手動賦值,數字轉換:undefined爲NaN,null爲0)

2.4 基本數據類型綜述

2.5 數組(typeof返回object) 

2.6 條件與循環 

  2.6.1 if條件表達式 (if(a)若是a未定義會產生警告,能夠用if(typeof a !=="undefined"),用三元運算符代替?:)

      (switch語句,case比對爲true執行冒號後語句, break跳出switch[可選],default可選)

  2.6.2 循環(while、do while、for、for in不可代替,遍歷數組或對象【此處可深刻跟forEach和each比較】

2.7 註釋(單行//,多行/**/)

2.8 本章小結

2.9 練習題

一、若是咱們再控制檯中執行下列語句,結果分別是什麼?爲何?

var a; typeof a  //undefined
var s='1s';s++   //NaN,自增自減必須針對Number類型(區別s+=1,值爲'1s1')
!!'false'        //true,'false'轉換爲true,兩次取反還爲true
!!undefined      //false
typeof -Infinity //number
10 % '0'         //NaN
undefined==null  //true,默認轉換爲false==false爲true
false===''       //false
typeof '2E+2'    //string
a=3e+3;a++       //3000,a++本行取值爲a,下一行爲a+1

二、執行下面的語句後,v的值會是什麼?

>>> var v = v || 10;

若是將v分別設置爲100、0、null,或者卸載它(即delete v),結果又將是什麼?

var v=v||10;     //v=10,undefined默認轉換爲false 
v=100;v=v||10;   //v=100
v=0;v=v||10;     //v=10,0默認轉換爲false
v=null;v=v||10;  //v=10,null默認轉換爲false
delete v;v=v||10;//v=10,delete後爲undefined(同上第一行)

三、編寫一個打印乘法口訣表的腳本程序。(提示:使用嵌套循環來實現。)

var res="\n";
for(var i=1;i<=9;i++){
    for(var j=1;j<=i;j++){res+=i+"*"+j+"="+i*j+" "}
    res+="\n"
}
console.log(res)
/*
1*1=1 
2*1=2 2*2=4 
3*1=3 3*2=6 3*3=9 
4*1=4 4*2=8 4*3=12 4*4=16 
5*1=5 5*2=10 5*3=15 5*4=20 5*5=25 
6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36 
7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49 
8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64 
9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81
*/

 

第三章:函數

3.1 什麼是函數 (一組代碼)

  3.1.1 調用函數

  3.1.2 參數(已定義形參,少傳實參默認undefined,多傳被忽略,也可以使用內建的arguments)

3.2 預約義函數

  3.2.1 parseInt()(轉換爲整數,第二個參數可選:設置進制類型,通常默認十進制,0x開頭默認16,0開頭默認8)

  3.2.2 parseFloat()(轉換爲十進制浮點數,可接受指數形式"123e-2"爲1.23)

  3.2.3 isNaN()(肯定是否爲數字,由於NaN===NaN爲false不可用)

  3.2.4 isFinite()(檢測是無窮大Infinity返回false不然爲true,isFinite(NaN)返回false)

  3.2.5 URI的編碼與反編碼(encodeURI()、encodeURICompent()和反轉函數decodeURI()、decodeURICompent())

  3.2.6 eval()(將字符串當作JS腳原本執行)

  3.2.7 alert()(不解釋)

3.3 變量的做用域(注意:沒有塊級做用域;不用var聲明默認爲全局變量;聲明前置)

3.4 函數也是數據(typeof function(){}返回function,函數是賦值給變量的一種數據,只是含代碼和可調用)

  3.4.1 匿名函數(能夠做爲參數傳遞個其餘函數[回調函數],用來執行一次性任務[自調函數])

  3.4.2 回調函數(能夠傳遞匿名函數減小全局變量,能夠將一個函數調用委託給另外一個函數,提高性能)

  3.4.3 回調示例(以下修改後只須要一次函數調用就夠了,使用匿名函數代替addOne)

//兩個函數共同處理時的數據傳遞
function multiplyBytwo(a,b,c){
    var i,ar=[];
    for(i=0;i<3;i++){ar[i]=arguments[i]*2;}
    return ar;
}
function addOne(a){return a+1;}
var myarr=multiplyBytwo(10,20,30)
for(var i=0;i<3;i++){myarr[i]=addOne(myarr[i])}
myarr //[21,41,61]
//回調函數方式
function multiplyBytwo(a,b,c,callback){
    var i,ar=[];
    for(i=0;i<3;i++){ar[i]=callback(arguments[i]*2);}
    return ar;
}
var myarr=multiplyBytwo(10,20,30,function(a){return a+1;})
myarr
//[21,41,61]

  3.4.4 自調函數(封閉做用域,不產生全局變量,缺點不可重複調用)

  3.4.5 內部私有函數(函數內部的函數:減小命名衝突;私有化)

  3.4.6 返回函數的函數(return返回一個函數)

  3.4.7 能重寫本身的函數(即爲函數從新賦值)

3.5 閉包

  3.5.1 做用域鏈(沒有塊級做用域,只有函數做用域,函數內可訪問自身和父級做用域中變量,函數外不可訪問函數內私有變量)

  3.5.2 詞法做用域(每一個函數定義時建立本身的環境即做用域)

function f1(){var a=1;f2()}
function f2(){return a}
f1()//a is not defind 變量a是f1函數的私有變量,f2被定義時(不是執行)爲全局函數,它沒法在全局做用域中找到私有變量a

  3.5.3 利用閉包突破做用域鏈(在函數內部傳遞或返回給全局空間)

function f(){var a=1; return function(){ return a}}
var n=f();
n(); //1,內部匿名函數可訪問私有變量a,返回這個匿名函數,將它賦值給n,而後執行n,便可訪問私有變量a
var n;
function f(){var a=1;n=function(){ return a}}
f();n()//1,定義一個全局變量n,執行f()後在內部定義了n能夠訪問內部變量,同時沒有用var它是屬於全局
function f(a){var n=function(){ return a};a++;return n}
var m=f(123)
m()//124返回++更新後的值,n前面是賦值而調用執行是return的時候,故函數綁定的是做用域自己,不是變量或變量當前返回值
//循環中的閉包
var arr=[];
for(var i=0;i<3;i++){
    arr[i]=(function(x){return x})(i)
}
arr[0]//0利用自調函數將i賦值給局部變量x,來避免調用做用域自己(即i更新後的值3)

  3.5.4 Getter與Setter(兩個額外函數用來訪問和設置不想暴露給外部的私有變量)

  3.5.5 迭代器

function setup(arr){
    var i=0;
    return function(){ return arr[i++]}
}
var next=setup(['a','b','c']);
next()//a
next()//b
next()//c

3.6 本章小結

3.7 練習題

一、編寫一個將十六進制值轉換爲顏色的函數,以藍色爲例#0000FF應被表示成‘rgb(0,0,255)’,而後將函數命名爲getRGB()

function getRGB(color){
    var rgb=[parseInt('0x'+color.slice(1,3)),parseInt('0x'+color.slice(3,5)),parseInt('0x'+color.slice(5,7))];
    return 'rgb('+rgb[0]+","+rgb[1]+","+rgb[2]+")";
}
getRGB("#00ff00")//"rgb(0,255,0)"

二、若是在控制檯中執行如下各行,分別會輸出什麼內容?

parseInt(1e1)//10
parseInt('1e1')//1,遇到不明字符截止
parseFloat('1e1')//10,可接受指數類型
isFinite(0/10)//true
isFinite(20/0)//false
isNaN(parseInt(NaN))//true

 三、下面代碼中,alert彈出的內容是什麼?(2)

var a=1;
function f(){
  var a=2;
  function n(){alert(a)}
  n()      
}
f()//2

四、如下全部示例都會彈出「Boo!」警告框,請解釋其中的緣由?

var f=alert;
eval('f("Boo!")')//將內置alert賦值給f,再用eval編譯,等同直接alert
var e,f=alert;
eval('e=f')('Boo!')//e=f=alert
(function(){
    function(){return alert}
})()('Boo!')//自調函數返回alert

 

第4章 對象

4.1 從數組到對象(數組等於數字鍵值的對象,對象的鍵值能夠不加引號,除了js保留字數字開頭或者特殊字符外)

  4.1.1 元素、屬性、方法(數組元素、對象屬性,若屬性爲函數則稱爲方法)

  4.1.2 哈希表、關聯型數組(即對象)

  4.1.3 訪問對象屬性(點語法a.b和中括號語法a[b],中括號語法適用於屬性名爲變量)

  4.1.4 調用對象的方法(同屬性和調用函數相同,a.b()或a[b]())

  4.1.5 修改屬性與方法

  4.1.6 使用this值(對象方法內部,可用this代替這個對象,即當前對象的意思)

  4.1.7 構造器函數(使用new操做符,能夠在建立同時接受一些參數)

  4.1.8 全局對象(全局屬性和函數,,默認爲瀏覽器(window)宿主對象的屬性和方法)

  4.1.9 構造器屬性(字面量法建立的對象,constructor默認爲Object())

function Hero(name){this.name=name;}
var h2=new Hero("aaa")
var h3=new h2.constructor("bbb")
h3.name //bbb,h2.constructor===Hero

  4.1.10 instranceof操做符(返回一個對象是否是摸個指定構造器所建立的,如a={},a instanceof Object//true)

  4.1.11 返回對象的函數(工廠模式)

function factory(name){
  return { name:name}  
}
var o=factory('one')
o.name//"one"
o.constructor//Object()
function C(){this.a=1}
var c=new C()
c.a//1
function C2(){this.a=1;return {b:2}}
var c2=new C2()
c2.a//undefined,這裏構造器返回的再也不是包含a的this對象
c2.b//2,而是return返回的對象(僅在構造函數return返回對象時發生,若返回非對象類型,仍然返回this對象)

  4.1.12 傳遞對象(複製對象傳遞的是引用,修改將影響它所引用的原對象 )

  4.1.13 對象比較(兩個對象引用相同對象時爲true,若是不一樣對象,即便方法屬性相同也爲false)

  4.1.14 Firebug控制檯中的對象

4.2 內建對象

  4.2.1 Object(全部對象的父級對象,空對象默認含有constructor屬性,toString和Valueof方法)

  4.2.2 Array(數組也是對象,因此繼承了Object的屬性和方法,數組長度length可設置,超出則建立undefined,小於則多餘被移除)

        (數組的特有方法:push添加、pop減小、sort排序、join字符串鏈接、slice截取、splice替換)

  4.2.3 Function(函數也是對象,默認屬性constructor和prototype,特有方法call和apply,arguments類數組它的callee返回自身,用於匿名遞歸調用)

  4.2.4 Boolean

  4.2.5 Number(特有方法:toFixed、toPrecision、toExponential)

  4.2.6 String(方法:toUpperCase、toLowerCase、charAt、indexOf、lastIndexOf、slice和substring、split、concat)

  4.2.7 Math(屬性爲常量不可修改,方法random、floor、ceil、max、min、pow、sqrt、sin、cos、atan。。)

  4.2.8 Date

  4.2.9 RegExp(兩種匹配內容的方法test、exec,以正則表達式爲參數的字符串方法match、search、replace、split)

  4.2.10 Error(使用try、catch及finally處理錯誤,throw new RangeEror拋出自建錯誤對象)

4.3 本章小結

4.4 練習題

一、請看下列代碼,請問這裏的的this指向的是全局對象仍是對象o?

function F(){
  function C(){return this;}//函數執行默認爲window調用,this指window全局對象
  return C();//C()執行並返回了window
}
var o=new F();//當構造函數返回對象時,新建對象等於返回的對象,因此o===window

二、下面代碼執行的結果是什麼?

function C(){this.a=1;return false;}
console.log(typeof new C()) //object,new C()等於建立了一個對象

三、下面這段代碼的執行結果又將是什麼?

c=[1,2,[1,2]];
c.sort();//[1,[1,2],2]
c.join('--');//'1--1,2--2'
console.log(c);//[1,[1,2],2]

四、在String()構造器不存在的狀況下自定義一個MyString()的構造器函數。並要讓建立的對象經過如下測試:

var MyString=function(str){this.str=str;this.init()}
MyString.prototype={
  constructor:MyString,
  init:function(){
      var that=this;
      for(var i in that.str){that[i]=that.str[i]}
      that.length=+i+1;
  },
  toString:function(){return this.str},
  valueOf:function(){return this.str},
  charAt:function(n){return isNaN(Number(n))?this[0]:this[Number(n)]},
  concat:function(s){ return this.str+s},
  slice:function(a,b){
      var s='';
      b=b>0?b:this.length+b;
      for(var i=a;i<b;i++){s+=this[i]}
      return s;
  },
  split:function(s){
      var str='',arr=[];
      for(var i=0;i<this.length;i++){if(this[i]==s){arr.push(str);str=''}else{str+=this[i];}}
      arr.push(str)
      return arr;
  }
}
var s=new MyString('hello')
s.length //5
s[0] //h
s.toString() //hello
s.valueOf() //hello
s.charAt(1) //e
s.charAt('2') //l
s.charAt('e') //h
s.concat(' world!') //hello world!
s.slice(1,3) //el
s.slice(0,-1) //hell
s.split('e') //["h","llo"]
s.split('l') //["he","","o"]

五、更新上面的MyString()構造器,爲其添加一個reverse()方法

MyString.prototype.reverse=function(){
    var str='';
    for(var i=this.length-1;i>=0;i--){str+=this[i]}
    return str;
}

六、在Array()構造器以及相關數組的文本標示法都不存在的狀況下,自定義一個相似的MyArray()構造器,並令其經過如下測試; 

var MyArray=function(arr){this.arg=arguments;this.init()}
MyArray.prototype={
  constructor:MyArray,
  init:function(){
      var that=this;
      for(var i in that.arg){that[i]=that.arg[i];}
      that.length=+i+1;
  },
  toString:function(){
    var that=this,str='';
    for(var i=0;i<that.length;i++){str+=(that[i]+[i==(that.length-1)?'':','])}
      return str;
  },
  push:function(s){this[this.length]=s;this.length++;return this.length;},
  pop:function(){ this.a=[];this.length--;delete this[this.length]; for(var i=0; i<this.length;i++){this.a[i]=this[i]};return this.a},
  join:function(b){var that=this,str='';
    for(var i=0;i<that.length;i++){str+=(that[i]+[i==(that.length-1)?'':b])}
      return str;}
}
var a=new MyArray(1,2,3,'test')
a.toString() //1,2,3,test
a.length //4
a[a.length-1] //test
a.push('boo') //5
a.toString() //1,2,3,test,boo
a.pop() //[1,2,3,test]
a.join(',') //1,2,3,test
a.join(' isn\'t ') //1 isn't 2 isn't 3 isn't test

七、在Math對象不存在的狀況下,建立一個相似的MyMath對象,併爲其添加如下方法:

  ◆ MyMath.rand(min,max,inclusive)--隨機返回min到max區間中的一個數,而且在inclusive爲true時爲閉區間(默認)

  ◆ MyMath.min(array)返回目標數組中的最小值

  ◆ MyMath.max(array)返回目標數組中的最大值

var MyMath={
  rand:function(min,max,inc){
    var i=true;if(!arguments[2]){i=false;}
    function r(n){return Math.floor((new Date().getTime()*9301+49297)%233280/233280*n);}
    if(i){return r(max-min+1)+min;}else{return r(max-min)+min;}
  },
  sort:function(arr,f){
    var l=arr.length,temp=arr[0];
    if(l>=2){for(var i=1;i<l;i++){temp=(temp-arr[i])*f>0?temp:arr[i];}}
    return temp;
  },
  min:function(array){return this.sort(array,-1)},
  max:function(array){return this.sort(array,1)}
}
console.log(MyMath.rand(5,10,true))//隨機5-10
console.log(MyMath.min([131,53,21]))//21
console.log(MyMath.max([88,44,99]))//99
相關文章
相關標籤/搜索