js學習筆記 day6

 
## 1.js的線程

<script>

//線程:一個線程一次只能處理一件事情,多個線程就能夠多個事情同時進行
//JS是單線程的!
//JS中,分了三個任務
//1.渲染任務
//2.js的代碼執行任務
//3.事件處理任務(事件隊列)
 
//JS代碼的執行順序
//1.先把主任務(代碼任務)執行完畢
//2.再去執行次要的任務(包括setTimeOut和setInterval中的回調函數中的代碼)
//setTimeOut
//至少在指定的時間後執行指定回調函數
//由於要等主任務中的代碼執行完畢以後,纔回去檢查,setTimeOut的回調函數,有沒到執行時間
//問題代碼
         for(var i = 0 ; i < 10; i++){
         setTimeout(function()
         console.log(j);
         },0);
        }
         //解決問題的代碼
for(var i = 0; i< 3; i++){
 
function foo(j){
//var j;
 
       //j = 實參
                  //j = i
return function(){
console.log(j);
};
}
//0
var f = foo(i);
setTimeout(f, 0);
}
</script>

## 2.緩存

<script>
//緩存:cache
 
//緩存的做用,就是將一些經常使用的數據,存儲起來,提供使用,提高性
 
//CDN Content Delivery Network
 
//數據庫 高併發
//非關係型數據庫(內存型數據庫) MongoDB Redis
 
//網站靜態頁面緩存機制
//將網頁靜態化,存儲在服務器端
</script>
## 3.關於使用遞歸解決斐波那契數列問題的性能分析和優化

<script>
1.使用數組存儲數列,雖然能夠提高性能,可是有侷限性
//能夠求5的 也能夠求10的,可是要求100呢 100000呢
var arr = [1, 1, 2, 3, 5, 8, 13, 21, 34];


2. //定義一個緩存數組,存儲已經計算出來的斐波那契數
//1.計算的步驟
//1.先從cache數組中去取想要獲取的數字
//2.若是獲取到了,直接使用
//3.若是沒有獲取到,就去計算,計算完以後,把計算結果存入cache,而後將結果返回
 
// var cache = [];
//
// function fib(n){
// //1.從cache中獲取數據
// if(cache[n] !== undefined){
// //若是緩存中有 直接返回
// return cache[n];
// }
// //若是緩存中沒有 就計算
// if(n <= 2){
// //把計算結果存入數組
// cache[n] = 1;
// return 1;
// }
// var temp = fib(n - 1) + fib(n - 2);
// //把計算結果存入數組
// cache[n] = temp;
// return temp;
// }
//
// console.log(fib(6));


var count =0 ;
function createFib(){
var cache = [];
function fib(n){
count ++;
//1.從cache中獲取數據
if(cache[n] !== undefined){
//若是緩存中有 直接返回
return cache[n];
}
//若是緩存中沒有 就計算
if(n <= 2){
//把計算結果存入數組
cache[n] = 1;
return 1;
}
var temp = fib(n - 1) + fib(n - 2);
//把計算結果存入數組
cache[n] = temp;
return temp;
}
return fib;
}


3.把下一個知識點應用進來,建立緩存容器

function createCache(){
var cache = {};
return function (key, value) {
//若是傳了值,就說名是設置值
if(value !== undefined){
cache[key] = value;
return cache[key];
}
//若是沒有傳值,只穿了鍵,那就是獲取值
else{
return cache[key];
}
}
}
 
var count =0 ;
function createFib(){
var fibCache = createCache();
function fib(n){
count ++;
//1.從cache中獲取數據
if(fibCache(n) !== undefined){
//若是緩存中有 直接返回
return fibCache(n) ;
}
//若是緩存中沒有 就計算
if(n <= 2){
//把計算結果存入數組
fibCache(n , 1) ;
return 1;
}
var temp = fib(n - 1) + fib(n - 2);
//把計算結果存入數組
fibCache(n, temp) ;
return temp;
}
 
return fib;
}


var fib = createFib();
// console.log(fib(6));
fib(5);
console.log(count);
count = 0;
fib(6);
console.log(count);
count = 0;
fib(20);
console.log(count);
count = 0;
fib(21);
console.log(count);
count = 0;
 
</script>
## 4.jquery緩存實現的分析

<script>
//eleCache
//typeCache
//classCache
//eventCache
 
function createCache(){
//cache對象中以鍵值對的形式存儲咱們的緩存數據
var cache = {};
//index數組中該存儲鍵,這個鍵是有順序,能夠方便咱們作超出容量的處理
var index = [];
return function (key, value) {
//若是傳了值,就說名是設置值
if(value !== undefined){
//將數據存入cache對象,作緩存
cache[key] = value;
//將鍵存入index數組中,以和cache中的數據進行對應
index.push(key);
 
//判斷緩存中的數據數量是否是超出了限制
if(index.length >= 50){
//若是超出了限制
//刪除掉最先存儲緩存的數據
//最先存入緩存的數據的鍵是在index數組的第一位
//使用數組的shift方法能夠獲取並刪除掉數組的第一個元素
var tempKey = index.shift();
//獲取到最先加入緩存的這個數據的鍵,可使用它將數據從緩存各類刪除
delete cache[tempKey];
}
}
//若是沒有傳值,只傳了鍵,那就是獲取值
// else{
// return cache[key];
// }
return cache[key];
}
}
 
var eleCache = createCache();
eleCache("name","高金彪");
console.log(eleCache("name"));
var typeCche = createCache();
</script>

## 5.沙箱


<script>
//沙箱
//與外界隔絕的一個環境,外界沒法修改該環境內任何信息,沙箱內的東西單獨屬於一個世界
 
//360沙箱模式
//將軟件和操做系統進行隔離,以達到安全的目的
 
//蘋果手的app使用的就是沙箱模式去運行
//隔離app的空間,每一個app獨立運行
 
//JS中的沙箱模式
//沙箱模式的基本模型
 
// (function(){
// var a = 123;
// })();
 
var sum = 0;
for(var i = 1; i<=100;i++){
sum+=i;
}
console.log(sum);
 
var a =123;
 
(function(){
 
//在沙箱中將全部變量的定義放在最上方
 
//中間就放一些邏輯代碼
 
//最後,若是須要,就給外界暴露一些成員(經過window)
 
var sum = 0;
for(var i = 1; i<=100;i++){
sum+=i;
}
console.log(sum);
})();
 
//爲何要使用當即執行函數表達式(IIFE)
//由於IIFE不會在外界暴露任何的全局變量,可是又能夠造成一個封閉的空間
//恰好能夠實現沙箱模式


//jQuery當中的沙箱模式
(function(win){
 
var itcast = {
getEle:function () {
 
}
}
 
//若是須要在外界暴露一些屬性或者方法,就能夠將這些屬性和方法
//加到window全局對象上去
//可是這window全局對象不能夠直接引用,由於直接引用會破壞沙箱原則
//因此咱們選擇使用傳參的形式將 window對象 傳入沙箱內
//此時沙箱內使用window對象的時候,不會再去全局搜索window對象
//而使用的就是沙箱內部定義的形參
 
win.itCast = win.$ = itcast;
 
})(window)


//沙箱模式通常應用在書寫第三方框架
//或者爲第三方框架書寫插件
//或者書寫功能獨立的一些組件
 
//沙箱模式的優點
//1.沙箱模式使用的是IIFE,不會再外界暴露任何的全局變量,也就不會形成全局變量污染
//2.沙箱中的全部數據,都是和外界徹底隔離的,外界沒法對其進行修改,也就保證了代碼的安全性


//js中沙箱模式的實現原理就是
//函數能夠構建做用域!上級做用域不能直接訪問下級做用域中的數據
</script>
## 6.函數的四種調用模式

<script>
//1.函數模式
//this指向window全局對象
 
//2.方法模式
//this指向調用這個方法的對象
 
//3.構造函數模式
//this 使用new建立出來的對象
 
//4.上下文模式
 
function test(){
console.log(this);
}
test();
 
var obj1 = {
test:function(){
console.log(this);
}
}
obj1.test();
 
function Person(){
console.log(this);
}
var obj =new Person();
 
</script>

## 7.構造函數的調用模式特徵

<script>
//構造函數調用模式的特徵
 
//1.構造函數的首字母要大寫
//2.通常狀況下和new關鍵字一塊兒使用
//3.構造函數中的this指定而是new關鍵字建立出來的對象
//4.默認的返回new建立出來的這個對象
 
function Person(){
 
}
 
var p = new Person();
//構造函數的返回值:
//默認返回new建立建立出來的對,如果值類型的數據,沒有影響
//如果對象類型,則返回這個對象,不會返回原來建立出來的對象
 
//1.工廠模式的構造函數
function Person(name,age){
var o = {
name:name,
age:age,
sayHello:function(){
 
}
}
return o;
}
 
var p = Person("張三", 18);
console.log(p);
//簡單工廠模式的構造函數 建立出來的對象 跟該構造函數無關
//簡單工廠模式的構造函數,實際的調用模式是 函數模式
 
//2.寄生式構造函數
function Person(name,age){
var o = {
name:name,
age:age,
sayHello:function(){
 
}
}
return o;
}
 
var p = new Person();
 
</script>
## 8.上下文函數調用模式

<script>
//上下文
//字面意思:上面的文字,下面的文字
 
//JS中的上下文
//context 執行環境的意思
//this
 
//在上下文調用模式中,能夠修改this的值,也就是能夠修改函數的調用方式
 
//使用以下兩個方法,能夠修改函數調用上下文,也就是this的值
//apply
//api文檔中的語法語句中 [] 表明括起來的東西無關緊要
//函數.apply(對象, 函數須要參數列表,是一個數組)
//call
//函數.call(對象,arg1,arg2,arg3...argn)
 
var name = "萊昂納多·自強·郭";
function sayHello(a, b) {
console.log(this.name + "吃了"+ (a * b) + "個饅頭");
}
// sayHello(); //
var obj = {
name:"尼古拉斯·電飯·鍋"
}
 
var arr= []
arr.push();
arr.push();
sayHello.apply(obj,arr); //
 
function test(a , b ,c){
 
}
sayHello.call(obj, 1, 2);
// sayHello.call(obj); //
//左值 右值
// function test(){
 
// this = 1;
 
// }
//call和apply的區別
//1.第一個參數都是要把this的指向修改爲爲指定的對象
//2.當函數須要參數的時候,那麼apply是用數組進行參數的傳遞
//3.而call是使用單個的參數進行傳遞
 
//call用於肯定了函數的形參有多少個的時候使用
//apply用於函數的形參個數不肯定的狀況
</script>



<script>
     //案例:求一個數組中的最大值
     var arr = [9, 1, 4, 10, 7, 22, 8];
     //Math.max
     Math.max(1,2,34,5);
 
     //apply方法的第二個參數 是一個數組
     // 在調用的時候,會將數組中的每個元素拿出來,做爲形參,挨個傳遞給函數
 
     //apply方法和call方法第一個參數傳遞null的時候,都表示爲函數調用模式
     //也就是將this指向window
     var max = Math.max.apply(null, arr);
     console.log(max);


     //案例:將傳入的參數打印,參數之間用-相互鏈接

     function foo() {
     return arguments.join("-");
 
     //僞數組不具備join方法,因此這個時候就要考慮去借用一下數組的join方法
     var str = Array.prototype.join.apply(arguments,["-"]);
     var str = [].join.apply(arguments,["-"]);
     return str;
     }
     var str = foo(1, 3, "abc", "ffff", 99) // 1-3-abc-ffff-99
     console.log(str);


     // var arr = [1,2,3,4];
     console.log(arr.join("-"));
 
     window.onload = function () {
     //案例:給頁面上全部的 div 和 p 標籤添加背景色
     var divs = document.getElementsByTagName("div");
     var ps = document.getElementsByTagName("p");
 
     var arr = [];
     //little tip: push方法能夠傳多個參數
     //arr.push(1,2,3,4,4,5)
 
     arr.push.apply(arr,divs);
     arr.push.apply(arr,ps);
 
     //若是使用arr.push()直接把divs傳進來
     //那麼至關於在arr中的第一個元素中存儲了一個divs數組
     //可是咱們須要把divs中的每個元素單獨的存入arr中
     //因此須要調用push方法的以下形式 push(1,2,4,4,5)
     //要實現這個形式的調用,就用到了apply方法的第二個參數的特性
     //在調用的時候,會將第二個參數的數組,拆成每個元素以(a,b,c,d,e,f,g) 傳入函數
 
     //至關於 arr.push(divs[0],divs[1],divs[..])
     arr.push(divs)


     for (var k = 0; k < arr.length; k++) {
     var ele = arr[k];
     ele.style.backgroundColor = "yellow";
     }
 
     for (var i = 0; i < divs.length; i++) {
     var div = divs[i];
     div.style.backgroundColor = "#ccc";
     }
    
     for (var j = 0; j < ps.length; j++) {
     var p = ps[j];
     p.style.backgroundColor = "#ccc";
     }
     }
</script>

## 9.call apply 和bind 的概述





<script>
    // call bind apply 改變函數中的this
    // 函數是一個對象
    // var fn = new Function();
    // function fn() {
    // }
    
    // 證實fn是Function的實例(對象)
    // console.log(fn.__proto__ === Function.prototype);
    
    // console.dir(fn);
    
    function fn(x, y) {
     console.log(this);
     console.log(x + y);
    }
    
    // fn(5, 6); // this->window
    
    // 1 調用函數,改變函數中的this
    // 2 第一個參數 設置函數內部this的指向
    // 其它參數,對應函數的參數
    // 3 函數的返回值 call的返回值就是函數的返回值
    // 4 測試
    // var obj = {
    // name: 'zs'
    // }
    // fn.call(obj, 5, 6);
    // apply 只有兩個參數
    // 1 調用函數,改變函數中的this
    // 2 第一個參數 設置函數內部this的指向
    // 第二個參數 是數組
    // 3 函數的返回值 apply的返回值就是函數的返回值
    // 4 測試
    // var obj = {
    // name: 'ls'
    // }
    // fn.apply(obj, [1, 2]);
    // bind
    // 1 改變函數中的this,不會調用函數,而是把函數複製一份
    // 2 第一個參數 設置函數內部this的指向
    // 其它參數,對應函數的參數
    // 3 函數的返回值 call的返回值就是函數的返回值
    // 4 測試
    var obj = {
     name: 'ww'
    }
    
    var f = fn.bind(obj, 5, 5);
    f();
</script>

















</script>
相關文章
相關標籤/搜索