js總結(原型和原型鏈,閉包等)

redhack發表於2017-09-17

一:資料儲存與賦值:
1:基本資料型別在棧中儲存變數名和值。
null和undefined,
都是資料型別,undefined表示未定義,有且僅有一個值,就是undefined,
null:表示空物件,typeof結果是object,和物件掛鉤用null
2:引用資料型別在棧中儲存變數名和在堆中儲存的地址編號。
引用型別就是物件包括:內建物件(String,boolean,Date,RegExp,Math).宿主物件(bom,dom),自定義物件
dom2:bom:瀏覽器物件模型,有window物件,window物件預設就存在的,
dom:文件物件模型,
事件委託:


  • html

  • css

  • js


var ul=document.getElementById('ul');
ul.onclick=function(e){
console.log(e.target.innerHTML)
}
dom2級註冊事件和解除事件從ie9開始支援,
二: 原型和原型鏈:
原型:每一個物件都有一個proto,每一個函式都有一個prototype,函式也是物件,所以也有proto,
原型屬性:隱士原型物件上的屬性
原型鏈:js每一個物件都有一個prototype屬性,指向他的原型物件,原型物件還有自己的原型,原型一環扣一環,直到某個物件的原型為null,這一級一級的鏈結構obj.
proto.proto就是原型鏈。
訪問一個物件的屬性時(obj.name),先從自由屬性中找,如果沒,就從隱式原型(obj.
proto)找,一直找,直到找到null,結束,找的過程形成的鏈條稱為原
鏈。
物件的隱式原型物件
proto===建立這個物件的構造器的prototype,這個物件的構造器的proto===object;Object的proto__為null.

 var arr=[]   arr.__proto__===Array.prototype
 var obj={}   obj.__proto__===Object.prototype
 function fn(){}  fn.__proto__===Function.prototype複製程式碼

三:物件與陣列:物件:是屬性的集合,分自有屬性,原型屬性:隱式原型物件上的屬性
var obj={
name:"js",
more:'node'
}
console.log(obj.name);//或 obj['name'] //訪問
delete obj.name //刪除屬性,屬性的configurable必須為true
for(var p in obj){
console.log(obj[p]); //遍歷
}
obj.hasOwnProperty(name);//判斷是否有某個自有屬性,
陣列:批量定義資料。
陣列的方法:join():將陣列以某種符號連線變成字串,
reverse():將陣列中元素倒置
concat():將兩個陣列練成一個陣列,
sort():排序
slice():擷取陣列長度,包頭不包尾
splice():新增刪除於一體。
push,pop,shift,unshift
陣列去重: var aa=[1,3,5,4,3,3,1,4]
function arr(arr) {
var result=[]
for(var i=0; i<arr.length; i++){
if(result.indexOf(arr[i])==-1){ //沒有返回-1
result.push(arr[i])
}
}
console.log(result)
}
arr(aa);
統計各個元素出現的個數:
var aa=[1,3,5,4,3,3,1,4]
// console.log(aa.indexOf(89)); //沒有則為-1
function count(arr){
var obj={};
for(var i=0;i<arr.length;i++){
if(obj.hasOwnProperty(arr[i])){
obj[arr[i]]=obj[arr[i]]+1;
}else{
obj[arr[i]]=1;

            }
        }
        return obj;
    }
字串:方法,concat:字串連線,
charAt():獲取指定索引的字元
indexof():獲取指定字元的索引,從左到右,找到第一個,
lastindexof():獲取指定字元的索引從右到左,找到第一個
splice():擷取
toUpperCase(),toLowerCase()大小寫轉換
replace():替換複製程式碼

四:閉包定義:在函式的外部可以訪問函式內部的變數。
閉包會延長變數的生命週期,
1:function a(){
var i=1;
function b(){
console.log(i);
}
return b;
}
var f=a();
f();//2 i沒被回收
f();//3
2:


  • h5

  • css3

  • es6


var lis=document.getElementsByTagName('li');
for(var i=0;i<lis.lenght;i++){
lis[i].onclick=(function(index){
return function(){
console.info(index);
}
})(i);
};
五:this的指向
1:在函式內部this永遠都指向window物件,在函式外部也指向window
function fn(){
function fn2(){
console.log(this);
}
fn2();
};
fn(); //window
立即執行函式中:
(function (){
"use strict"
console.log(this)
})() //undefined 避免汙染全域性

    2:全域性執行
        console.log(this) //window
        node環境下指向global
        嚴格模式node環境下:this 為undefined

    2:在物件的方法中,指向當前物件
    var obj={
        name:'js',
        write:function(){
            console.log(this.name);
        }
        }
    }或者
    var obj={
        name:'js',
        write:fn
    }
    function fn(){
        console.log(this.name)
    }
    obj.write(); //js
    把物件的方法賦值給一個變數,呼叫這個變數時,指向window
    var f=obj.write;
    f() //window
    回撥函式中的this
    var obj={
        name:'js',
        foo0:function(){
            console.log(this)
        },
        foo:function(){
            console.log(this);
            setTimeout(this.foo0,1000) //window 物件
        }
    }
    obj.foo()
    3:通過new建立的函式,會指向當前物件
        function F(){
              console.log(this);
        };
      var f=new F();
      console.log(f);

    4:出現在物件的事件函式中,會指向當前物件
     <button onclick="add(this)">點選</button>
      function add(value){
          console.log(value);//button
    }
    5:可以通過applay和call改變this的指向
      (1)var obj={
          name:'node'
      };
      function say(){
        console.log(this);
        console.log(this.name);
      };
      say.call(obj);
      (2)call與applay的區別,引數形式不一樣
      var obj={
              name:'node'
         };
      function add(x,y){

          return x+y;
      };
      var result=add.call(obj,1,2); //函式呼叫call,
      var result2=add.apply(obj,[2,3]);//函式呼叫apply,[]陣列形式
      console.log(result,result2);
      call和applay
    六:js原型和繼承:
        _proto_:(隱式原型):是物件內部的屬性,指向另一個物件的原型

        prototype:(顯示原型)是函式的屬性,指向函式的原型。
        顯式原型的作用是用來實現基於原型的繼承與屬性的共享。
        隱式原型的作用是構成原型鏈,同樣用於實現基於原型的繼承,
        js的oop程式設計
            1:生成例項物件的最原始模式
            var cat={
                name:'',
                color:''
            }
            改進:function Cat(name,color){
                return {name:name,color:color}
            }
            建構函式模式:
                function Cat(name,color){
                    this.name=name;
                    this.color=color;
                    this.type="貓類動物";
                    this.eat=function(){

                    },
                    this.say=function(){}
                }
                var cat1=new Cat(name,color)
                var cat2=new cat(name,color)
                cat1,cat2的costructor就是 Cat()
                cat1.eat==cat2.eat //false
            instanceof運算子:驗證原型物件與例項物件之間的關係
            cat instanceof Cat//true
            建構函式建立的例項,每個type屬性和eat方法都是重複的內容,多佔用一些記憶體,既不環保,也缺乏效率,可以讓type屬性和eat方法只生成一個例項,
            prototype模式:每一個建構函式都有一個prototype屬性,指向另一個物件,這個物件的所有屬性和方法都會被建構函式的例項繼承,可把那些不變的屬性和方法定義在prototype物件上,
            function Cat(name,color){
                this.name=name;
                this.color=color;
            }
            Cat.prototype.eat=function(){

            }
             var cat1=new Cat(name,color)
            var cat2=new cat(name,color)
            此時 cat1.eat==cat2.eat //true
            prototype模式的驗證方法,
             isPrototypeof方法,
             Cat.prototype.isPrototypeOf(cat1) //true
             每一個例項都有一個hasOwnPrototype()方法
             判斷是本地屬性還是繼承自prototype物件的屬性
             in運算子可以判斷某個例項是否有某個屬性,不管是不是本地屬性
             “name” in cat1 //true 
             in運算子還可以遍歷
             淺拷貝:
             深拷貝:
             function deepCopy(p,c){
                 var c=c||{};
                 for(var i in p){
                     if(typeof[i]==="object"){
                         c[i]=(p[i].constructor===Array)?[]:{};
                         deepcopy(p[i],c[i]);
                     }else{
                         c[i]=p[i];
                     }
                 }
                 return c;
             }
    七:js拖拽實現:
        .box{
              width: 150px;
              height: 180px;
              border:1px solid red;
              position: relative;
             }
             .fangdajing{
              width:80px;
              height: 100px;

              background:url("./img/scope.png");
              position: absolute;
              left:0;
              top:0;
              display: none;
              cursor: move;
             }
      var box=document.getElementById('box');
      var fangdajing=document.getElementById('fangdajing');
      var xiaotu=document.getElementById("xiaotu");
      var fangdajing_left=0;
      var fangdajing_top=0;
      box.onmouseenter=function(){
        fangdajing.style.display="block";
      }
      box.onmouseover=function(e){
        fangdajing_left=fangdajing_left<0 ? 0:e.clientX-xiaotu.offsetLeft-fangdajing.offsetWidth/2;
        fangdajing_left=fangdajing_left> box.offsetWidth-fangdajing.offsetWidth ?  box.offsetWidth-fangdajing.offsetWidth : fangdajing_left;
        fangdajing_top=fangdajing_top<0 ? 0:e.clientY-xiaotu.offsetTop;-fangdajing.offsetHeight/2;
        fangdajing_top=fangdajing_top> box.offsetHeight-fangdajing.offsetHeight ? box.offsetHeight-
        fangdajing.offsetHeight : fangdajing_top;
        fangdajing.style.left=fangdajing_left+"px";
        fangdajing.style.top=fangdajing_top+"px";
      }
      <div class="box" id="box">
      <img class="" id="xiaotu" src="./img/TB1gFOyJVXXXXXLXpXXXXXXXXXX-150-118.png"/>
      <div class="fangdajing" id="fangdajing"></div>
      <div class="fangdahou"></div>
    </div>
八:js中的正則
 1:建立正則:構造器方式 var p=new RegExp("\d","mgi") 
 字面量:var p=/\d/mgi
 正規表示式的構成:界定符,原子,修飾符:mgi
 2:正則的使用:test()方法:檢測目標字串是否有符合要求的字串
 var p=/a/
 var str="abc"
 console.log(p.test(str)) //true
 exec():把符合要求的字串找出來,
 console.log(p.exec(str)) //index:0
 3:原子:表示一個字元 a-z,A-Z,-0-9 加上i:表示不區分大小寫複製程式碼

js效能優化,
1:定義區域性變數
js搜尋引擎在區域性作用域鏈中搜尋的深度越大,操作也會消耗更多的事件,
例:var d1=document.getElementById('d1'),d2=document.getElementById('d2');
改為:var d=document;
var d1=d.getElementById('d1'),d2=d.getElementById('d2')
2:能不使用閉包,就不使用
3:物件屬性和陣列元素的速度比變數慢,
因此當多次引用一個陣列中元素或物件的屬性時,可以通過定義一個變數獲得效能提升,firbox瀏覽器在優化陣列時讓實際效能優於變數
5:不要再陣列挖的更深,巢狀多層陣列操作很慢
6:遍歷一個集合內的元素時,不要使用for-in迴圈,
因為for-in不僅遍歷額外的陣列項還需要更多的時間。
7:修改css類而不是樣式,
因為修改css區域性樣式更高效,區域性樣式發生改變時會引為迴流
8:node自動化部署
9:重構和迴流:
重構:改變每個元素外觀時所觸發的瀏覽器行為,比如顏色,背景等樣式發生了改變而進行的重新構造新外觀的過程,重構不會引發頁面的重新佈局,不一定伴隨著迴流。
迴流:指的是瀏覽器為了重新渲染頁面的需要而進行的重新計算元素的幾何大小和位置的,他的開銷是非常大的,迴流可以理解為渲染樹需要重新進行計算,一般最好觸發元素重構,避免元素迴流;比如通過新增類新增css樣式,而不是直接在dom上設定的,需要操作某一塊元素時,最好使其脫離文件流,這樣就不會引起迴流了,比如設定position:absolute或fixed,或者display:none,操作結束後再顯示,
10:http中的長連線短連線
短連線:建立連線,資料傳輸,關閉連線,建立連線,資料傳輸,關閉連線
長連線:建立連線,資料傳輸...(保持連線)..資料傳輸--關閉連線
11:設計模式的規則:
開閉原則:一段程式對外擴充套件是開發的,
共分3大類:建立型模式:單例模式,工廠模式,原型模式
結構型模式:裝飾者模式,
行為型模式:觀察者模式,策略模式,

12:瀏覽器渲染過程:
dns查詢,tcp連線,http請求,響應,伺服器響應,客戶端渲染(處理html標記並構建dom樹,處理css標記並構建css樹,將dom和css樹合併為一個樹,根據dom樹來佈局)。
此http與https:https是在http和tcp有一層ssL層,https比http安全。
http的長連線和端連線,http屬於應用層協議,在傳輸層使用tcp協議,在網路層使用ip協議負則網路路由和定址問題,tcp協議主要解決如何在ip層之上,可靠的傳輸資料包,使在網路的另一端收到發端發出的所有資料包,並且順序與發出順序一致,http協議是無狀態的,指的是協議對於事物處理沒有記憶能力,伺服器不知道客戶端是什麼狀態,開啟伺服器上的網頁和你之前開啟的無任何練習
阻塞渲染css與javascript:當 HTML 解析器(HTML Parser)被指令碼阻塞時,解析器雖然會停止構建DOM,但仍會識別該指令碼後面的資源,並進行預載入。預設情況下,css被認為是阻塞渲染的資源,意味著瀏覽器不會渲染任何已處理的內容,直至cssom構建完畢,js不僅可以查詢和修改dom和cssom,cssom構建時,javascript將暫停,
存在阻塞的 CSS 資源時,瀏覽器會延遲 JavaScript 的執行和 DOM 構建。另外複製程式碼

當瀏覽器遇到一個 script 標記時,DOM 構建將暫停,直至指令碼完成執行。
JavaScript 可以查詢和修改 DOM 與 CSSOM。
CSSOM 構建時,JavaScript 執行將暫停,直至 CSSOM 就緒。
所以,script 標籤的位置很重要。實際使用時,可以遵循下面兩個原則:
CSS 優先:引入順序上,CSS 資源先於 JavaScript 資源。
JavaScript 應儘量少影響 DOM 的構建。
css:
<style> p { color: red; }</style> <link rel="stylesheet" href="index.css">
這樣的 link 標籤(無論是否 inline)會被視為阻塞渲染的資源,瀏覽器會優先處理這些 CSS 資源,直至 CSSOM 構建完畢。

渲染樹(Render-Tree)的關鍵渲染路徑中,要求同時具有 DOM 和 CSSOM,之後才會構建渲染樹。即,HTML 和 CSS 都是阻塞渲染的資源。HTML 顯然是必需的,因為包括我們希望顯示的文字在內的內容,都在 DOM 中存放,那麼可以從 CSS 上想辦法。
<link href="index.css" rel="stylesheet"> <link href="print.css" rel="stylesheet" media="print"> <link href="other.css" rel="stylesheet" media="(min-width: 30em) and (orientation: landscape)">
第一個資源會載入並阻塞。
第二個資源設定了媒體型別,會載入但不會阻塞,print 宣告只在列印網頁時使用。
第三個資源提供了媒體查詢,會在符合條件時阻塞渲染。
最容易想到的當然是精簡 CSS 並儘快提供它。除此之外,還可以用媒體型別(media type)和媒體查詢(media query)來解除對渲染的阻塞.
改變阻塞模式
13:事件模型:dom0級事件模型是早期的事件模型所有瀏覽器都支援的,
<p id = 'click'>click me</p> 1: document.getElementById('click').onclick = function(event){ alert(event.target); } 2:var click = document.getElementById('click'); click.onclick = function(){ alert('you click the first function'); }; click.onclick = function(){ alert('you click the second function') }
dom0級只能註冊一個同一型別的函式,註冊多個會覆蓋,
事件捕獲和事件冒泡:ie8及以下是不支援的,
dom2級可以註冊多個相同的事件型別不覆蓋,在DOM2級中使用addEventListener和removeEventListener來註冊和解除事件(IE8及之前版本不支援)。這種函式較之之前的方法好處是一個dom物件可以註冊多個相同型別的事件,不會發生事件的覆蓋,會依次的執行各個事件函式。

<div id = 'outer' style = 'margin: 100px 0 0 100px; width: 200px;height: 200px; background: red;'>
    <div id="inner" style = 'margin-left:20px; width: 50px;height:50px; background: green;'></div>
</div>

    var click = document.getElementById('inner');
    click.addEventListener('click',function(){
        alert('click one');
    },false);
    click.addEventListener('click',function(){
        alert('click two');
    },false);複製程式碼

14:1: touchslider外掛實現輪播圖

.focus{ 
    width:320px;
    height:150px; 
    margin:0 auto;
    position:relative;
    overflow:hidden;  
    }
.focus .hd{ 
    width:100%; 
    height:5px; 
    position:absolute; 
    z-index:1;
    bottom:0;
    text-align:center;  
    }
.focus .hd ul{
    overflow:hidden; 
    display:-moz-box; 
    display:-webkit-box;
    display:box; height:5px;
    background-color:rgba(51,51,51,0.5);  
    }
.focus .hd ul li{ 
    -moz-box-flex:1; 
    -webkit-box-flex:1;
    box-flex:1;
    }
.focus .hd ul .on{ 
    background:#FF4000;
    }
.focus .bd{
    position:relative;
    z-index:0;
    }
.focus .bd li img{ 
    width:100%; 
    height:150px; 
}
.focus .bd li a{ 
    -webkit-tap-highlight-color:rgba(0, 0, 0, 0);

}
header{
    margin-top:45px;
}
.focus{
    width:100%;
    height:auto;
}
.focus .bd li img{
    height:auto;
}
.focus .hd{
    width:auto;
    height:8px;
    left:50%;
    -webkit-transform:translateX(-50%);   /*translate中的百分數是相對於自身的*/
    -moz-transform:translateX(-50%);
    -ms-transform:translateX(-50%);
    -o-transform:translateX(-50%);
    transform:translateX(-50%);
    bottom:4px;
}
.focus .hd ul{
    height:8px;
    background: none;
}
.focus .hd ul li{
    width:8px;
    height: 8px;
    -webkit-border-radius:50%;
    -ms-border-radius:50%;
    -moz-border-radius:50%;
    -o-border-radius:50%;
    border-radius:50%;
    background-color: rgba(255, 255, 255, 0.6);
    margin:0 5px;
    font-size: 0;
}
.focus .hd ul .on{
    background-color: #099fde;
}
<header>
        <div id="focus" class="focus">
            <div class="hd">
                <ul></ul>
            </div>
            <div class="bd">
                <ul>
                    <li><a href="#"><img src="images/1.jpg" /></a></li>
                    <li><a href="#"><img src="images/2.jpg" /></a></li>
                    <li><a href="#"><img src="images/3.jpg" /></a></li>
                    <li><a href="#"><img src="images/4.jpg" /></a></li>
                </ul>
            </div>
        </div>
        <script type="text/javascript">
            TouchSlide({ 
                slideCell:"#focus",
                titCell:".hd ul", //開啟自動分頁 autoPage:true ,此時設定 titCell 為導航元素包裹層
                mainCell:".bd ul", 
                effect:"leftLoop", 
                autoPlay:true,//自動播放
                autoPage:true //自動分頁
            });
        </script>
    </header>複製程式碼
2:swiper外掛http://www.swiper.com.cn/download/index.html複製程式碼

15:跨域:是由於同源策略引起的,域名:包括:協議,主機,埠,
16:

相關文章