国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JavaScript_函數

DirtyMind / 3505人閱讀

摘要:所謂閉包,是指詞法表示包括不必計算的變量的函數。回調函數回調函數執行回調函數中的回調函數的返回值用來遍歷數組中的每一項數組中有幾項,那么傳遞進去的匿名回調函數就需要執行幾次。

初始函數

Function類型,即函數的類型。

典型的JavaScript函數定義:

function 函數名稱(參數表){
    //函數執行部分
    return ;
}
//注意:參數列表直接寫形參名即可

return語句:return返回函數的返回值并結束函數運行
函數也可以看做數據來進行傳遞
參數列表相當于函數入口return 語句相當于函數出口

函數可以作為參數來傳遞。

 function test ( a ) {
        a();
    }
    test(function () {
        alert(1);
    });
    

函數可以嵌套定義

function test2(){
    function test3(){
        alert(1);
    }
    test3();
}
test2();
定義函數

三種定義函數的方式:

function語句形式
函數直接量形式
通過Function構造函數形式定義函數

//1 function 語句式
function test1 () {
    alert(1);
}

//2 函數直接量 (ECMAScript 推薦)

var test2 = function () {
    alert(2);
}


//3 function 構造函數式
var test3 = new Function("a","b","return a+b;");  //最后一個參數是函數結構體 
test3(10,20);
function語句 Function構造函數 函數直接量
兼容 完全 js1.1以上 js1.2以上版本
形式 句子 表達式 表達式
名稱 有名 匿名 匿名
性質 靜態 動態 靜態
解析時機 優先解析 順序解析 順序解析
作用域 具有函數的作用域 頂級函數(頂級作用域) 具有函數作用域

靜態動態的區別

var d1 = new Date();
var t1 = d1.getTime();

for ( var i=0; i<10000000; i++ ) {
    
//                function test1 () {} // 342ms  //在函數體只會被聲明一次 ,其它地方并不再解析,就可以調用 。 //靜態 //只會編譯一次,放入內存中。

    var test2 = function () {}  //354ms
        
//                    var test3 = new Function();  //8400ms  //每次執行,都是重新new一個 函數。 //new 完之后, 就銷毀了。不占用內存。動態創建一次。
    
}
var d2 = new Date();
var t2 = d2.getTime();

console.log( t2 - d1 );

解析順序

function f () {
    return 1;
}                 // 函數1

alert( f() );        //返回值為4 說明第1個函數被第4個函數覆蓋

var f = new Function("return 2;");        // 函數2 

alert( f() );        //返回值為2 說明第4個函數被第2個函數覆蓋

var f = function () { 
    return 3; 
}            // 函數3

alert( f() );           //返回值為3 說明第2個函數被第3個函數覆蓋

function f () { 
    return 4; 
}                 // 函數4

alert(f());        //返回值為3 說明第4個函數被第3個函數覆蓋

var f = new Function("return 5");         // 函數5 

alert(f());    //返回值為5 說明第3個函數被第5個函數覆蓋    

var f = function(){
    return 6;
}            // 函數6

alert(f());        //返回值為6 說明第5個函數被第6個函數覆蓋

函數作用域

var k = 1 ; 
function t1(){
    var k = 2 ; 
//    function test(){return k ;}  //2
//  var test = function(){ return k};  //2
    var test = new Function("return k;");  //1   //new Function();  是會有頂級作用域
    alert(test());
}
t1();
函數的參數arguments

arguments對象,是實參的副本

//js 中 函數分為 : 形參,實參
function test ( a,b,c,d ) {
    
//                console.log( test.length ); //獲取形參的個數  4
    
    //函數的實際參數  內部就是使用一個數組去接收實際參數。 類數組對象
    //arguments 對象,只能在函數內部使用。
    //arguments 對象, 可以訪問函數的實際參數 (實參的副本)
//                console.log( arguments.length );  //2
//                console.log( arguments[0] ); //10
//                //  第一種方式:
//                if ( test.length === arguments.length ) {
//                    
//                    return a + b;
//                    
//                }
        
        //使用第二種 方式: 
        if ( arguments.callee.length === arguments.length ) {
            
            return a + b;
            
        }
    
    //arguments對象,  使用得最多的還是使用遞歸操作
//                arguments.callee; // 指向函數本身,函數體
    
}

test(10,20);
this對象的簡單理解

this對象是在運行時基于函數的執行環境綁定的

在全局函數中,this等于window,而當函數被作為某個對象的方法調用時,this等于那個對象。

也就是說this關鍵字總是指代調用者(誰調用了我,就指向誰)。

//this: this對象是指在運行時期基于執行環境所綁定的

var k = 10;

function test () {
    
    this.k = 20;
    
}

test();

console.log( test.k ); //undefined
call和apply方法

每一個函數都包含兩個非繼承而來的方法:call、apply。這倆個方法的用途都是在特定的作用域中調用函數,實際上等于設置函數體內this對象的值。

call、apply的用途之一就是傳遞參數,但事實上,它們真正強大的地方式能夠擴充函數賴以運行的作用域(使你的作用域不斷的去變化)。

使用call()、aplly()來擴充作用域的最大好處就是對象不需要與方法有任何耦合關系

fn.call(obj);
讓fn以運行,并且fn中的this以obj身份運行

將一個函數綁定到一個特定的作用域中,然后傳遞特定作用域中的參數。

//call, apply  簡單 用法: 綁定一些函數  用于傳遞參數  調用

function sum ( x,y ) {
    
    return x + y;
    
}

function call1 ( num1,num2 ) {
    
    return sum.call(this,num1,num2);
    
}

function apply1 ( num1,num2 ) {
    
    return sum.apply(this,[num1,num2])
    
}

//將一個函數綁定到一個特定的作用域中,然后傳遞特定作用域中的參數。

console.log( call1(10,10) );
console.log( apply1(20,10) ); 

//擴充作用域,底層也經常使用這兩個方法,用于綁定不同的作用域。
//把一個函數賦給一個對象, 賦完之后,還可以重用,賦給另外一個對象。

window.color = "pink";

var obj = {
    color: "tan"
}

function showColor () {
    
    console.log( this.color );
    
}

showColor.call(window);  
//                showColor.call(this);
showColor.apply(obj);

call方法簡單的實現

function test1 ( a,b ) {
    
    return a + b;
    
}

//自定義對象
function Obj ( x,y ) {
    
    return x * y;
    
}

var obj = new Obj();

//掛載到對象上
obj.method = test1;

//執行該函數
obj.method(10,20);

//執行完后刪除
delete obj.method;
bind

ES5中提供一個bind()方法。
為函數綁定一個執行時候的作用域。
將該方法綁定Function的原型上,因此定義一個function就有該方法,bind()添加作用域的時候,方法沒有執行,在方法執行的時候,作用域會變成綁定兌現的作用域。

function b () {
    console.log(this.title);
}

function Book ( title ) {
    this.title = title;
}

var book = new Book("javascript");

// apply , call 特點:調用就執行
//            b.call(book);
//            b.apply(book);

// 當執行一個函數的時候更改作用域 
var bBindfn = b.bind(book);

// 執行更改作用域
bBindfn();
執行環境和作用域鏈概念

執行環境(execution context)是javascript中最為重要的一個概念。執行環境定義了變量或函數有權訪問的其他數據,決定了它們各自的行為。每一個執行環境都有一個與之關聯的變量對象,環境中定義的所有變量和函數都保存在這個對象中。雖然我們的代碼無法訪問這個對象,但是解析器在處理數據時會在后臺執行它。

全局執行環境是最外圍的一個執行環境。根據ECMScript實現所在的宿主環境不同,表示執行環境的對象也不一樣。

每一個函數都有自己的執行環境。當執行流進一個函數時,函數的環境就會被推入一個環境棧中。而在函數執行之后,棧將其環境彈出,把控制權返還給之前的執行環境。當代碼在一個環境中執行時,會創建變量對象的一個作用域鏈(scope chain)。作用域鏈的用途,是保證對執行環境有權訪問的所有變量和函數的有序訪問(控制代碼的訪問權限)。

var color1 = "blue";

function changeColor () {
    
    var color2 = "red";

    function swapColor () {
        
        var color3 = color2;  //color3 = "red"
        color2 = color1; //color2 = "blue"
        color1 = color3;  //color1 = "red"
        
        console.log( color1,color2,color3 ); 
        
    }
    
    swapColor();
    
}

changeColor();

//環境變量  可以一層一層的向上進行追溯  可以訪問它的上級 環境(變量和函數)
// 作用域鏈 具有層級關系
//在大型程序中,全局變量,盡量少使用,因為全局變量總是最后一次搜索。 防止全局變量污染。//很少去定義全局變量,效率比較慢。

垃圾收集和塊級作用域的概念 垃圾收集

javascript是一門具有自動垃圾收集機制的編程語言。開發人員不必關心內存分配和回收問題。

垃圾回收器也是每隔一段時間去進行回收。

離開作用域的值將被自動標記為可以回收,因此將在垃圾收集期間被刪除。標記清除是目前主流的垃圾收集算法。這種思想是給當前不使用的值加上標記,然后回收其內存。

//垃圾收集  ,標記清除 (模擬)

function test () {
    
    var a = 10;   //mark - 被使用
    var b = 20;   //mark - 被使用
    
}

test();  //執行完畢 之后 ,a,b又被標記使用。  mark - 沒有被使用
//在間隔時間中 回收。  如果mark 沒有被使用, 則回收。
//引用計數(模擬)
//如果變量被引用 ,  count = 1;
function test2 () {

    var a = 10;   //count = 1;
    var b = 20;

    var c;
    c = a;  //count++ = 2; //a 被 c 所使用 ,引用。

    a = 50;  //count--; //重新被賦值 count--   //等待 count 為 0 的時候, 垃圾回收機制  就回收

}
塊級作用域

javascript里面沒有塊級作用域的概念,所以在使用if、for時候要格外的小心。

javascript模擬塊級作用域 (塊級作用域,相當于內部的執行體,一個執行環境)
利用 IIEF的特性

//當函數執行之后, 變量就被回收            
    
function test () {
    
    (function () {  //函數有一個多帶帶的作用域,外面無法訪問到 i
        
        for ( var i=0; i<=5; i++ ) {
            
            console.log( i );
            
        }
        
    })();
    
    console.log( i );  //報錯,無法找到
    
}

test();
閉包 Closure

閉包與函數有著緊密的關系,它是函數的代碼在運行過程中的一個動態環境,是一個運行期的、動態的概念。

所謂閉包,是指詞法表示包括不必計算的變量的函數。也就是說,該函數能夠使用函數外定義的變量。

在程序語言中,所謂閉包,是指語法域位于某個特定的區域,具有持續參照(讀寫)位于該區域內自身范圍之外的執行域上的非持久型變量值能力的段落。這些外部執行域的非持久型變量神奇地保留它們在閉包最初定義(或創建)時的值

理解閉包,必須要對于作用域鏈的概念非常的清楚。

var name = "xiao A";

var obj = {
    
  name : "xiao B",
    
  getName: function(){
        
        return function(){
            
            return this.name;
            
        }
        
    }
    
};

console.log(obj.getName()());  //xiao A
//類似:
//var zf = obj.getName();//全局作用域
//zf();
var name = "xiao A";

var obj = {
    
  name : "xiao B",
    
  getName: function(){
        
    var self = this;    
        
        return function(){
            
            return self.name;
            
        }
        
    }
    
};

//console.log( obj.getName().call(obj) );
console.log( obj.getName()() );

//閉包: 一個函數, 可以訪問另外一個作用域中的變量
//封閉性,(類似食品包裝袋一樣,封閉起來,保質期延長,變量的訪問范圍的延長) //private 起到一個保護變量的作用

//1 level 
function f(x){ //2 level
    
    var temp = x;  //局部變量    //temp 標記 已經沒有被使用
      
    return function(x){ //3 level   (function 有一個執行域)
        
        temp += x;   //temp 下一級作用域仍然被引用 , 標記為 使用
        
        alert(temp);
    
    }
    
}                

//js 垃圾回收機制,當函數執行完畢后,內部所有的局部變量都集體的被回收。

var a = f(50);

a(5);  //55

a(10); //65

a(20); //85
回調函數

回調函數執行

回調函數中的this

回調函數的返回值

forEach

// forEach:用來遍歷數組中的每一項
// 1. 數組中有幾項,那么傳遞進去的匿名回調函數就需要執行幾次。
// 2. 每一次執行匿名函數的時候,還傳遞了三個參數值:數組中的當前項item,當前項的索引index,原始的數組input
// forEach方法中的this是arr,匿名函數回調函數的this默認是window
var arr = [10, 234, 23, 76, 7666, 34];
arr.forEach(function(item, index, input) {
  input[index] = item * 10; // 操作之后,修改了原數組
  console.log(arguments);
});

var obj = {name: "zf"};
// arr.forEach(function(item, index) {
//   console.log(this);
// }.call(obj)); // 給forEach賦值的是時候,首先把匿名函數執行,把匿名函數中的this變為obj,把匿名函數執行的返回結果undefined賦值給foreach

arr.forEach(function(item, index) {
  console.log(this, "---");
}.bind(obj)); // bind 只是預先處理,先把this轉為參數的對象,到后續該執行的時候才執行。


// 不管是forEach,還是map都支持第二個參數,第二個參數表示:把匿名函數中的this進行修改。
arr.forEach(function() {
  console.log(this, "this");
}, obj);

forEach兼容處理

// 兼容處理
Array.prototype._forEach = function(callback, context) {
  content = content || window;
  if ("forEach" in Array.prototype) {
    this.forEach(callback, context);
    return;
  } 
  // IE6-8,執行回調邏輯
  for (var i=0; i

map

var arr = [10, 234, 23, 76, 7666, 34];
arr.map(function(item, index, input) { // 原有數組不變
  console.log(arguments);
  return item * 10;
});
// map和forEach非常相似,都是用來遍歷數組中的每一項的值
// 區別:map的回調函數中支持return返回值,return的是什么,相當于把數組中的這一項改變為什么(但是并不影響原來的數組,只是相當于把原數組克隆一份,把克隆的這一份的數組中的對應項改變)

map兼容處理

Array.prototype._map = function(callback, context) {
  context = context || window;
  if ("map" in Array.prototype) {
    this.map(callback, context);
    return;
  } 
  // IE6-8,執行回調邏輯
  var resArr = [];
  for (var i=0; i
柯理化函數思想

柯理化函數思想:一個JS預處理思想

核心:利用函數執行可以形成一個不銷毀的私有作用域的原理,把需要預先處理的內容都存儲在這個不銷毀的作用域中,并且返回一個匿名函數,執行的都是匿名函數,把匿名函數中,把之前的預先存儲的值進行相關操作處理即可。

var obj = {name: "zf"};
function fn(num1, num2) {
  console.log(this, num1, num2)
}

// 把傳遞進來的callback這個方法中的this預先處理為context
function bind(callback, context) {
  context = context || window;
  var outArg = Array.prototype.slice.call(arguments, 2);
  return function(ev) {
    var innerArg = Array.prototype.slice.call(arguments, 0);
    callback.apply(context, outArg.concat(innerArg));
  }
}

// document.body.onclick = fn; // fn 中的 this是document.body. num1是 MouseEven對象
document.body.onclick = fn.bind(obj, 100, 200); // 除了預先處理了this和需要手動傳遞的參數值以外,把瀏覽器默認給傳遞的鼠標事件對象也進行預先處理,傳遞到最后一個參數。
document.body.onclick = bind(obj, 100, 200)
// document.body.onclick = function() {
  // console.log(this); // this -->  document.body
// }

// window.setTimeout(fn.bind(obj), 0);
// window.setTimeout(bind(fn, obj, 100, 20), 0); // 給定時器綁定方法,然后定時器到達時間的時候,讓fn執行,并且讓fn中的this變為obj

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/79728.html

相關文章

  • JavaScript中的面向對象(object-oriented)編程

    摘要:對象在中,除了數字字符串布爾值這幾個簡單類型外,其他的都是對象。那么在函數對象中,這兩個屬性的有什么區別呢表示該函數對象的原型表示使用來執行該函數時這種函數一般成為構造函數,后面會講解,新創建的對象的原型。這時的函數通常稱為構造函數。。 本文原發于我的個人博客,經多次修改后發到sf上。本文仍在不斷修改中,最新版請訪問個人博客。 最近工作一直在用nodejs做開發,有了nodejs,...

    JerryZou 評論0 收藏0
  • 深入理解Javascript原型關系

    摘要:如下所示在規范中,已經正式把屬性添加到規范中也可以通過設置和獲取對象的原型對象對象之間的關系可以用下圖來表示但規范主要介紹了如何利用構造函數去構建原型關系。 前言 在軟件工程中,代碼重用的模式極為重要,因為他們可以顯著地減少軟件開發的成本。在那些主流的基于類的語言(比如Java,C++)中都是通過繼承(extend)來實現代碼復用,同時類繼承引入了一套類型規范。而JavaScript是...

    ethernet 評論0 收藏0
  • 講清楚之 javascript原形

    摘要:構造函數和實例都通過屬性指向了原形。代碼示例是構造函數的實例的屬性與的屬性保存的值相等,即他們指向同一個對象原形。 講清楚之javascript原型 標簽: javascript javascript 中原形是一個比較難于理解的概念。javascript 權威指南在原形這一章也花了大量的篇幅進行介紹,也許你已經讀過javascript 權威指南,或者已經是讀第N篇了,然而這篇文章的目...

    高勝山 評論0 收藏0
  • JavaScript 工廠函數 vs 構造函數

    摘要:當談到語言與其他編程語言相比時,你可能會聽到一些令人困惑東西,其中之一是工廠函數和構造函數。好的,讓我們用構造函數做同樣的實驗。當我們使用工廠函數創建對象時,它的指向,而當從構造函數創建對象時,它指向它的構造函數原型對象。 showImg(https://segmentfault.com/img/bVbr58T?w=1600&h=900); 當談到JavaScript語言與其他編程語言...

    RayKr 評論0 收藏0
  • 和少婦白潔一起學JavaScript

    摘要:我們已經回答了的構造函數和原型都是誰的問題,現在牽扯出來一個,我們繼續檢查的構造函數是全局對象上屬性叫的對象的原型是個匿名函數,按照關于構造函數的約定,它應該是構造函數的屬性我們給這個對象起個名字,叫。 我不確定JavaScript語言是否應該被稱為Object-Oriented,因為Object Oriented是一組語言特性、編程模式、和設計與工程方法的籠統稱謂,沒有一個詳盡和大家...

    DevTTL 評論0 收藏0

發表評論

0條評論

DirtyMind

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<