function應用技巧

1、new function的用法

1.用法一javascript

此種用法的跟使用{}的區別是:它比較靈活,能夠在內部定義變量、函數等java

var obj = new function(){
   var a = 1; 
   var b = 2;
   this.total = a + b;
   return a + b; // 被忽略
}

至關於:閉包

var obj = {
   total : 3
 }

2.用法二app

此種用法就是閉包而已函數

var test = new function(){

   var a = 1;
   var b = 2;

   return function(c){
      return a + b + c;
   }

}

test(3);//6

至關於:this

var test = (function(){

   var a = 1;
   var b = 2;

   return function(c){
      return a + b + c;
   }

})();

test(3);//6

2、Function.prototype.apply.call的用法

function log(){
   if(window.console){
         // 第一個參數是apply要執行的函數,第二個參數爲context,第三個參數爲要執行函數的參數列表
         Function.prototype.apply.call(console.log,console,arguments);
         // Function.apply.call(console.log,console,arguments); // 也是能夠的。
   }
}

3、構造函數中return

1.構造函數return基本類型的值prototype

function Person(){

   var a = 2;

   this.a = a;

   return a;

}

var p = new Person();

console.dir(p); // 此時p的值並非2,而是一個有一個屬性a其值爲2的對象

2.構造函數return Object類型的值指針

function Person(){

    var a = 2

    return {

       name:"李彥峯",
       a : a

    }

}
var p = new Person();

console.dir(p); // 此時p爲一個對象 {name:"李彥峯",a:2}

結論:code

  1. 在構造器中 return ,若是是基本類型的值,那麼使用 new 操做符將會按照預期,返回一個對象,就至關於構造函數中的 return 語句不存在同樣對象

  2. 在構造器中若是 return 的是一個Object類型(function/基本類型的包裝類型/Object類型),那麼 new 操做符就至關於不存在同樣,也就是說,js引擎會把 return 出去的引用值做爲變量,而不會把 new 出來的新對象的引用賦值給相應的變量。。

4、函數的屬性

  • 函數的屬性列表

    1. arguments

    2. caller

    3. length

    4. name

    5. prototype(這個屬性先略過)

上述的屬性均可以經過 函數名.屬性來引用,length是形參的個數。若是是函數表達式的話,name是空串。

function outer(a,b,c){
    console.log(outer.arguments); // [1,2,3,4]
    console.log(outer.caller); // null
    console.log(outer.length); // 3
    console.log(outer.name); // outer
    function inner(){
        console.log(inner.arguments); // []
        console.log(inner.caller); // 打印出整個函數體
        console.log(inner.length); // 0
        console.log(inner.name); // inner
 
        // 內部函數訪問外部函數的屬性    
        console.log(arguments.callee.caller.arguments); // [1,2,3,4]
        // console.log(inner.caller.arguments);  // [1,2,3,4]
        console.log(arguments.callee.caller.caller); // null
        // console.log(inner.caller.caller); // null
        console.log(arguments.callee.caller.length); // 3
        // console.log(inner.caller.length); // 3
        console.log(arguments.callee.caller.name); // outer
        // console.log(inner.caller.name); // outer
    }
    inner();
}
outer(1,2,3,4);

5、局部變量

對於局部聲明的重複變量,只有第一個聲明有效,也就是說,js引擎會忽略除了第一個以外的全部的聲明

// 第一種
 function test(){
   
     var name = "李彥峯";
     var name; 
     console.log(name); // 李彥峯

 }

 // 第二種
 function test(){
    
     var name;
     var name = "李彥峯";
     console.log(name); // 李彥峯
    
 }

注意:第二種好像不符合 對於局部聲明的重複變量,只有第一個聲明有效的說法,其實也是符合的,由於js引擎會對函數進行2輪處理,局部變量的聲明在第1輪處理(變量聲明提高),因此第1輪會保證只有一個name被聲明,第2輪才進行局部變量的初始化(代碼執行到賦值語句才進行初始化),即會把第1輪聲明的局部變量賦值。。

嚴格模式下不能經過函數名.arguments的方式訪問arguments對象,不能訪問caller屬性

6、arguments

arguments對象擁有一個callee屬性,該屬性是一個指針,指向擁有這個arguments對象的函數

arguments對象內部屬性值是跟參數一一對應的,改變其中一個的值都會影響另一個。

看代碼:

function test(a,b,c){
    console.log(arguments); // [1,2,4]
    a = 8;
    console.log(arguments); // [8,2,4]
    arguments[1] = 909;
    console.log(b); // 909
    console.log(arguments); // [8,909,4]
}
test(1,2,4);

注意:嚴格模式下不能訪問arguments對象的callee屬性

相關文章
相關標籤/搜索