JavaScript Functions

JavaScript Functions

 

Parameters

js的函数可以接受多个参数

function sumOnSteroids() {
    var i, res = 0, number_of_params = arguments.length;
    for (i = 0; i < number_of_params; i++) {
        res += arguments[i];
    }
    return res;
}

console.log(sumOnSteroids(1, 2, 43));//46
console.log(sumOnSteroids(1, 2, 3, 4));//10
console.log(sumOnSteroids(1, 2, 5, 6, 7));//21

 

Predefined functions(预定义的函数)

There are a number of functions that are built into the JavaScript engine and are available for you to use. Let's take a lookat them. While doing so, you'll have a

chance to experiment with functions, their arguments and return values, and become comfortable working with functions. Following is a list of the built-in functions:

  • parseInt()

  • parseFloat()

  • isNaN()

  • isFinite()

  • encodeURI()

  • decodeURI()

  • encodeURIComponent()

  • decodeURIComponent()

  • eval()

var abc = "121221";
console.log(parseInt(abc));//121221
console.log(isNaN(abc));//false

内建的函数可以直接使用

eval函数

eval('var ii = 2');
console.log(ii); //2

 

Scope of variables

It's important to note, especially if you have come to JavaScript from another language, that variables in JavaScript are not defined in a block scope(JavaScript的变量不在块级作用域里定义), but in a function scope(在函数作用域). This means that if a variableis defined inside a function, it's not visible outside of the function. However, if it's defined inside an if or a for code block, it's visible outside the block. The term(术语) "global variables"(全局变量) describes variables you define outside of any function (in the global program code), as opposed to(相反地) "local variables", which are defined inside a function(在一个函数内定义). The code inside a function has access to all global variables as well as to its own local ones.

示例代码:

var somevar = 12;

function dowork() {
    var n = somevar;
    console.log(n);//12
    if (n === 12) {
        var msg = "the value is 12";
    }
    console.log(msg);//the value is 12
}

dowork();

 

Functions are data

Functions in JavaScript are actually data. This is an important concept that we'll need later on. This means that you can create a function and assign it to a variable:

var f = function (a, b, c) {
    return a + b + c;
};
var f2 = function () {
    return "you are a pig";
};
console.log(f(1, 2, 3));//6
console.log(f2());//you are a pig
var f3 = f2;
console.log(typeof f3);//function

 

So, JavaScript functions are data, but a special kind of data with two important features:

  • They contain code

  • They are executable (they can be invoked)

 

Anonymous functions(匿名函数)

var f = function (a, b, c) {
    return a + b + c;
};

This is also often called an anonymous function(匿名函数) (as it doesn't have a name), especially when such a function expression is used even without assigning it to a variable. In this case, there can be two elegant(优雅地) uses for such anonymous functions:

  • You can pass an anonymous function as a parameter to another function.(当做一个参数进行传递) The receiving function can do something useful with the function that you pass.

  • You can define an anonymous function and execute it right away.(可以立即执行一个匿名函数)

 

Callback functions(回调函数)

When you pass a function, A, to another function, B, and then B executes A, it's often said that A is a callbackfunction. If A doesn't have a name, then you can say that it's an anonymous callback function.

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

function one() {
    return 1;
}

function two() {
    return 2;
}
var result1 = invokeAdd(
    function () {
        return 1;
    }, function () {
        return 2;
    });

var result2 = invokeAdd(one, two);
console.log(result1);//3
console.log(result2);//3

 

Immediate functions(self-invoking)

One good application of immediate (self-invoking) anonymous functions is when you want to have some work done without creating extra global variables. A drawback, of course, is that you cannot execute the same function twice. This makes immediate functions best suited for one-off or initialization tasks.

(function () {
    console.log("hello");
})();

(function (name) {
    console.log("hello," + name);
})("lyx");

使用Immediate functions返回值

var result = (function (name) {
    console.log("hello," + name);
    return "complete";
})("lyx");

console.log(result);//complete

 

Inner (private) functions

Bearing in mind that a function is just like any other value, there's nothing that stops you from defining a function inside another function:

function outer(param) {
    function inner(theinput) {
        return theinput * 2;
    }

    return 'The result is ' + inner(param);
}
console.log(outer(12));//The result is 24

在outer函数作用域外面访问不到inner函数

The benefits of using private functions are as follows:

  • You keep the global namespace clean (less likely to cause naming collisions)

  • Privacy—you exposeonly the functions you decide to the "outside world", keeping to yourself functionality that is not meant to be consumed by the rest of the application

 

Functions that return functions

没有return语句的函数返回undefined

function test() {
    console.log("so called");
}

console.log(test());//undefined

As mentioned earlier, a function always returns a value, and if it doesn't do it explicitly with return, then it does soimplicitly by returning undefined. A function can return only one value, and this value can just as easily be another function:

function a() {
    console.log('A!');
    return function () {
        console.log('B!');
    };
}
console.log(typeof a());//函数a返回的是一个函数function

var newFUnc = a();//执行函数a,并把返回值赋给newFunc变量
newFUnc();//执行函数a返回的函数

a()();//立即执行返回的函数

 

Function, rewrite thyself!

function a() {
    console.log('A!');
    return function () {
        console.log('B!');
    };
}

a = a();//打印A!
a();//打印B!

If you call this function for the first time, it will:

  • Alert A!(consider this as being the one-off preparatory work)

  • Redefine the global variable a, assigning a new function to it

 

Closures(闭包)

Scope chain

var global = 1;
function outer() {//函数作用域
    var outer_local = 2;

    function inner() {//一个内部函数inner()has access to all variables
        var inner_local = 3;
        return inner_local + outer_local + global;
    }

    return inner();
}

console.log(outer());//6

从这个示例中可以看到inner()函数可以访问到所有的变量,这就是作用域链的效果。

 

Breaking the chain with a closure

var a = "global variable";
var F = function () {
    var b = "local variable";
    var N = function () {
        //The function N has access to its private space, to the F() function's space, and to the global space.
        var c = "inner local";
        return b;
    };
    return N;
};

The function N has access to its private space, to the F() function's space, and to the global space. So, it can see b. Since F() is callable from the global space (it's a global function), you can call it and assign the returned value to another global variable. The result: a new global function that has access to the F() function's private space:

 

var inner = F();
var b = inner();
console.log(b);//local variable

另一个闭包的例子:

var inner; // placeholder
var F = function () {
    var b = "local variable";
    var N = function () {
        return b;
    };
    inner = N;
};
F();

A new function, N(),is defined inside F() and assigned to the global inner. During definition time, N() was inside F(), so it had access to the F() function's scope. inner() 

will keep its access to the F() function's scope, even though it's part of the global space:

var b = inner();
console.log(b);//local variable

 

A definition and closure

Every function can be considered a closure. This is because every function maintains a secret link to the environment (the scope) in which it was created. But, most of the time this scope is destroyed unless something interesting happens (as shown above) that causes this scope to be maintained.

Based on what you've seen so far, you can say that a closure is created when a function keeps a link to its parent scope even after the parent has returned. And, every function is a closure because, at the very least, every function maintains access to the global scope, which is never destroyed.

 

再看一个闭包的例子,这个闭包的例子是有关函数的参数的:

Function parameters behave like local variables to this function(函数的参数就像函数作用域中的本地变量一样), but they are implicitly(隐式的) created (you don't need to use var for them). You can create a function that returns another function, which in turn returns its parent's parameter:

function F(param) {
    var N = function () {
        return param;
    };
    param++;
    return N;
}

var inner = F(123);
var result = inner();
console.log(result);

Notice how param++was incremented after the function was defined and yet, when called, inner() returned the updated value. This demonstrates that 

the function maintains a reference to the scope where it was defined, not to the variables and their values found in the scope during the function definition.

 

Closures in a loop

function F() {
    var arr = [], i;
    for (i = 0; i < 3; i++) {
        arr[i] = function () {
            return i;
        };
    }
    return arr;
}

var arr = F();
console.log(arr[0]());//3
console.log(arr[1]());//3
console.log(arr[2]());//3

三次循环,每次循环保存当前循环的变量i,但从结果来看,没有得到我们想要的效果:

程序应该这样改:

function F() {
    var arr = [], i;
    for (i = 0; i < 3; i++) {
        arr[i] = (function (x) {
            return function () {
                return x;
            };
        }(i));
    }
    return arr;
}

var arr = F();
console.log(arr[0]());//0
console.log(arr[1]());//1
console.log(arr[2]());//2

Here, instead of just creating a function that returns i, you pass the ivariable's current value to another immediate function. In this function, ibecomes the local value x, and xhas a different value every time.

 

Alternatively(另外), you can use a "normal" (as opposed to an immediate) inner function to achieve the same result. The key is to use the middle function to "localize" the value of iat every iteration:

function F() {
    function binder(x) {
        return function () {
            return x;
        };
    }

    var arr = [], i;
    for (i = 0; i < 3; i++) {
        arr[i] = binder(i);
    }
    return arr;
}

var arr = F();
console.log(arr[0]());//0
console.log(arr[1]());//1
console.log(arr[2]());//2

 

Getter/Setter-Closures 

var getValue, setValue;
(function () {
    var secret = 0;
    getValue = function () {
        return secret;
    };
    setValue = function (v) {
        if (typeof v === "number") {
            secret = v;
        }
    };
}());

console.log(getValue());//0
setValue(123);
console.log(getValue());//123

In this case, the function that contains everything is an immediate function. It defines setValue()and getValue()as global functions, while the secretvariable remains local and inaccessible directly.

 

Iterator-Closures 

The last closure example (also the last example in the chapter) shows the use of a closure to accomplish an iterator functionality.

function setup(x) {
    var i = 0;
    return function () {
        return x[i++];
    };
}

var next = setup(['a', 'b', 'c']);
console.log(next());//a
console.log(next());//b
console.log(next());//c

For this example, let's just use a simple array and not a complex data structure. Here's an initialization function that takes an input array and also defines a secret pointer, i, that will always point to the next element in the array.

===========END===========

转载于:https://my.oschina.net/xinxingegeya/blog/291688

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值