JavaScript散亂(四、細(xì)節(jié))

js高級

案例問題

案例一:
let a={name:"測試"};
function test(obj){
    obj={name:"hehe"};
}
test(a);
console.log(a);//{name: "測試"}
說明:a傳入test中,obj重新賦值,obj的的形參的指向就變化了,此時其實(shí)obj={name:"hehe"};在函數(shù)執(zhí)行完畢就會被當(dāng)作垃圾回收,而a的指向是不變的。
案例二:
let a={name:"測試"};
function test(obj){
    obj.name="qiang";
}
test(a);
console.log(a);//{name: "qiang"}
說明:該案例對比案例一,該案例,obj持有的也是a同樣的
地址索引,所以,改變obj的name就是修改a的name屬性。
案例:原型
 function F(){

}
Object.prototype.a=function(){
    console.log("a()")
}
Function.prototype.b=function(){
    console.log("b()")
}
var f=new F()
f.a() //a()
f.b()   //報錯
F.a() //a()
F.b() //b()
說明:Function也是一個對象,派生于Object對象。
f是對象,不屬于Function類型,所以f.b()在F中找沒有,然后去Object中找也沒有。
F.a()執(zhí)行:F本身沒有a方法,去它的原型找,原型是Function(也是一個對象,通過其__proto__可知最后到了Object上面),原型上還沒有a方法只有b方法,繼續(xù)去Function的原型上找,所以找到了Object上面。

作用域和作用域鏈

全局作用域也就是window和函數(shù)作用域,不考慮es6的塊級作用域前提下,作用域個數(shù)=函數(shù)定義個數(shù)+1.
作用域鏈就是內(nèi)部作用域找不到去外級作用域找,最后到全局作用域。

案例一:
var a=100;
function test(){
    var a=200;
    function test1(){
        console.log(a)//200
    }
    test1();
}
test()
案例二:
var fn=function(){
    console.log(fn)
}
fn()//? (){console.log(fn)}
var obj={
    fn2:function(){
        console.log(this.fn2)//? (){console.log(fn)}
        console.log(fn2)// fn2 is not defined
    }
}
obj.fn2()
說明:對比案例一發(fā)現(xiàn),理論上console.log(fn2)應(yīng)該是可以找到的,但是實(shí)際上,obj內(nèi)部不是作用域,所以fn2
函數(shù)內(nèi)部找不到fn2之后,直接去上一級作用域也就是此時的window找也沒有。而案例一test是函數(shù),其也是作用域

內(nèi)存溢出和泄露

  • 內(nèi)存溢出:程序運(yùn)行需要的內(nèi)存超過了剩下的內(nèi)存時,就會拋出內(nèi)存溢出的錯誤
  • 內(nèi)存泄露:占用內(nèi)存沒有用但是又沒有即時釋放

例如:意外的全局變量,沒有即時清理的定時器或回調(diào)函數(shù),閉包

閉包

內(nèi)部函數(shù)持有外部函數(shù)的引用

function test(){
    let a=10;
    function test1(){
        console.log(a);
    }
    let t1=function(){
        console.log(a);
    }////////////
    return test1;
}
let t=test();
t();
t=null;
說明:兩個內(nèi)部函數(shù)的定義是有區(qū)別的,因為函數(shù)聲明提示,test1在test函數(shù)內(nèi)部第一行就聲明和定義一起完成,
t1聲明是在第一行但是定義是在其執(zhí)行完畢才定義(也就“/////”所在的一行).
注意因為t的引用問題,所以test函數(shù)執(zhí)行完畢也不會釋放
test函數(shù)本身和閉包的相關(guān)引用,所以可能造成內(nèi)存泄漏,
所以如果確定閉包不使用了,可以把對象值設(shè)置為null。
閉包案例一:
var name="The WIndow";
var obj={
    name:"obj",
    getName:function(){
        return function(){
            return this.name;
        }
    }
}
console.log(obj.getName()())//The WIndow
說明:因為obj調(diào)用所以getName內(nèi)部的this就是obj,但是
執(zhí)行完畢返回的是一個函數(shù)然后在執(zhí)行,相當(dāng)于就是在window直接執(zhí)行了該方法,所以內(nèi)部匿名函數(shù)的this就是window。
閉包案例二:
var name="The WIndow";
var obj={
    name:"obj",
    getName:function(){
        return ()=>{
            return this.name;
        }
    }
}
console.log(obj.getName()())//obj
說明:obj的getName函數(shù)沒有用箭頭函數(shù)。其內(nèi)部this還是obj,但是內(nèi)部匿名函數(shù)是箭頭函數(shù),指向調(diào)用者,此時指向obj所以輸出obj。
閉包案例三:
var name="The WIndow";
var obj={
    name:"obj",
    getName:()=>{
        return ()=>{
            return this.name;
        }
    }
}
console.log(obj.getName()())//The WIndow
說明:都是用箭頭函數(shù),則指向相當(dāng)于為最終調(diào)用者,即window
閉包案例四:
var name="The WIndow";
var obj={
    name:"obj",
    getName:function(){
        var that=this;
        return function(){
            return that.name;
        }
    }
}
console.log(obj.getName()())//obj
說明:that已經(jīng)指向getName函數(shù)作用域,也就是obj

瀏覽器內(nèi)部流程

瀏覽器一般都是多線程的,但是js是單線程執(zhí)行的,下圖是說明

QQ截圖20180608152428.png

初始化代碼都是在主線程執(zhí)行,且必須初始化代碼執(zhí)行完畢才能執(zhí)行其他代碼

setTimeout(()=>{
    console.log("執(zhí)行")
},0);
for(var a=0;a<10000000000;a++){}
說明:setTimeut是初始化代碼,但是內(nèi)部的回調(diào)函數(shù)不是初始化代碼,所以即使時間是0也會在初始化代碼執(zhí)行完畢之后才執(zhí)行

事件循環(huán)模型

eventloop會每次從callback隊列中每次取出一個執(zhí)行,但是是分線程,所以主線程如果耗時,則回調(diào)隊列
內(nèi)部也不會順利的立刻執(zhí)行。

事件循環(huán)模型.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時...
    歐辰_OSR閱讀 30,235評論 8 265
  • 第2章 基本語法 2.1 概述 基本句法和變量 語句 JavaScript程序的執(zhí)行單位為行(line),也就是一...
    悟名先生閱讀 4,556評論 0 13
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,653評論 1 32
  • 每只毛毛蟲都可以變成自己的蝴蝶。只不過,在變成蝴蝶之前,自己會先變成作繭自縛的蛹。在繭里邊面對自己制造的痛苦,任何...
    笨小貓Jolin閱讀 154評論 0 0
  • 有時候我會懊惱自己的退縮,我總害怕別人會拿鄙視的眼光看我,總是覺得如果凡事沖到前面會讓人感到討厭。 有時候我會沖動...
    人生只若初見kl閱讀 249評論 0 0

友情鏈接更多精彩內(nèi)容