走進JavaScript——重拾函數

建立函數

經過構造器的方式來建立函數,最後一個參數爲函數體其餘爲形參javascript

new Function('a','b','alert(a)')
/* function anonymous(a,b) {
        alert(a)
   }
*/

因爲函數體是經過字符串拼接的,所以咱們能夠用這個特性來實現代碼的組合java

function foo(){
    var a = 10;
    console.log(a);
}
new Function('say',foo + 'foo();console.log(say)')('Hello foo');
// 10
// Hello foo

// 實際上以上代碼是這樣的
function anonymous(say) {
  function foo(){
      var a = 10;
      console.log(a);
  }foo();console.log(say)
}

還能夠用這個特性來實現json字符串轉對象json

var json = '{a:123, b:456}';
new Function('return ' + json)();
// Object {a: 123, b: 456}

甚至咱們能夠利用它來實現重載運算符函數

function calc(num1,num2,operator){
    return new Function('return ' + num1 + operator + num2)();
}
console.log(calc(2,3,'+'));
console.log(calc(5,2,'-'));
// 5
// 3

咱們能夠將返回的函數做爲構造器來建立對象code

new new Function();
// Object {}

執行函數

函數名加()能夠執行一個函數對象

function foo(){
    console.log(123);
}
foo();
// 123

那若是沒有函數名呢token

function(){};
// Uncaught SyntaxError: Unexpected token (

也就是不支持直接這麼寫,咱們須要將以上函數改爲一段表達式,將函數進行運算就成表達式了ip

'' + function(){console.log(5)};
// "function (){console.log(5)}"

那麼怎麼執行它呢,在函數後面加()字符串

'' + function(){console.log(5)}();
// 5

以上代碼不太優雅對吧,咱們能夠用一個()將它包起來io

(function(){console.log(123)}());
// 123

()也是會進行運算的

(1) // 1

非惰性求值

只要你給函數傳遞參數它就會進行運算,並不會由於你沒有使用它

var a = 10;
(function(){}(a++,a++));
console.log(a); // 12

非惰性求值得另一個例子就是在使用alert時

var a = 1;
alert(a+=1,a++); // 2
console.log(a); // 3

第一個輸出2是由於alert只接受一個參數,但因爲函數是不限制參數個數的而且是非惰性求值因此alert中的第二個參數仍是會被運算只是沒有被alert使用罷了

函數中的callee、caller

callee的意義就在於當咱們使用匿名函數時能夠去調用函數自己

var a = 0;
(function(){
    if(a > 3) return;
    console.log(++a);
    arguments.callee();
}());
// 1
// 2
// 3
// 4

還有一種狀況是當咱們重寫函數時

var a = 0;
function foo(){
    if(a > 2)return;
    console.log(++a);
    foo = null;
    arguments.callee();
}
foo()
// 1
// 2
// 3

caller的意義就在於咱們可以知道此函數是被誰調用的

function f1(){
    f2();
}
function f2(){
    console.log(arguments.callee.caller);
}
f1();
/* function f1(){
    f2();
}
/*
相關文章
相關標籤/搜索