JavaScript援用范例——“Function范例”的注重要点

Function 范例

每一个函数都是Function 范例的实例。函数名实际上就是一个指向函数对象的指针,不会与某个函数绑定。

函数声明体式格局建立Function,语法以下:

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

函数表达式定义Function,用var 以下:

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

第二种要领不要忘记在末端加上分号

别的还能够运用Function 组织函数。如:

var sum = new function("x","y","return x + y");

异常不引荐运用这类情势。

怎样证实函数名仅仅是指向函数的指针呢:

var sum = function(x,y){
    return x + y;
};
console.log(sum(1,2)); //3

var anotherSum = sum;
console.log(anotherSum(1,1)); //2

sum = null;
console.log(anotherSum(10,10)); //20

没有重载

同名的背面的函数将会掩盖前面的函数。如:


function add(num){
    return num + 100;
}
function add(num){
    return num + 200;
}
console.log(add(100)); //300

用别的一种写法就能够很清晰的看出缘由。如:

var add = function(num){
    return num + 100;
}
add = function(num){
    return num + 200;
}
console.log(add(100)); //300

函数的声明与函数表达式(以及函数声明提拔)

解析器会领先读取函数声明,并使其在实行任何代码之前可用(可接见);至于函数表达式,则必需比及解析器实行到它地点的代码行,才会真正被诠释实行。如:

console.log(sum(1,1)); //2
function sum(x,y){
    return x + y;
}

以上代码可行,是因为在代码最先值钱,解析器就已经由历程一个名为函数声明提拔(function declaration hoisting)的历程,读取并将函数声明添加到实行环境中去。纵然声明函数的代码在挪用它的代码背面,JavaScript 引擎也能把函数声明提拔到顶部。

然则,假如把函数声明改成函数表达式,则会致使毛病。如:

console.log(sum(1,1)); 
var sum = function(x,y){
    return x + y;
}; //TypeError: undefined is not a function (evaluating 'sum(1,1)')

失利的缘由就在于函数位于初始化语句中,而不是一个函数声明。

也可同时运用函数声明和函数表达式,但在safari 浏览器中会失足。

作为值的函数

函数也能够作为值来运用,也就是能够将一个函数作为另一个函数的效果返回。如

function callFunction(someFunction,someArgument){
    console.log(someFunction(someArgument));
}
function addNum(x){
    return x + 100;
}
callFunction(addNum,100); //200

要接见函数的指针而不实行函数的话,必需去掉函数名背面的括号。

function compare(func,x,y){
    var num1 = func(x);
    var num2 = func(y);
    var array = [num1,num2];
    
    var result = array.sort(sortFunc);
    console.log(result.toString());
    document.write(result.join(" then "));
    
    
    function sortFunc(value1,value2){
        if (value1 > value2){
            return 1;
        }else if(value2 > value1){
            return -1;
        }else{
            return 0;
        }
    }
}

function add10(num){
        return num + 10;
    }

compare(add10,10000,999100); //10010 then 999110

函数内部属性

这里重要说一下callee属性、this属性以及caller属性。

callee属性的功用就是消弭函数名的耦合题目。如:

function min(num){
    if(num == 1){
        return 1;
    }else if(num < 1){
        return 0;
    }else{
        return min(num - 1);
    }
}

var result = min(100);
document.write(result);

上面这个min()函数假如改了函数名,函数内里也响应的须要修正函数名。但添加了callee属性,就不须要修正。如:

function mins(num){
    if(num == 1){
        return 1;
    }else if(num < 1){
        return 0;
    }else{
        return arguments.callee(num - 1);
    }
}

var result = mins(100);
document.write(result);

着就处理了耦合征象所带来的题目。

this这个特别对象的作用与Java 和C# 中的this 相似。this援用的是函数据以实行的环境对象——或许this值。如:

window.color = "red";
var obj = {color: "yellow"};

function show(){
    document.write(this.color);
}

show(); //red

obj.show = show;
obj.show(); //yellow

caller用来挪用当前函数的函数的援用(源代码)。如:

function sum(x,y){
    plus(x,y);
}

function plus(x,y){
    console.log(x + y);
    document.write("<pre>" + plus.caller + "</pre>");
}

sum(10,20);

如:


(
    function a(){
        document.write("function a");
        b();
        function b(){
            document.write("function b");
            alert(arguments.callee.caller);
        }
    }
)()

用arguments.callee 可能在某些浏览器中会致使毛病:

function sum(x,y){
    plus(x,y);
}

function plus(x,y){
    console.log(x + y);
    document.write("<pre>" + arguments.callee.caller + "</pre>");
}

sum(10,20);

函数属性和要领

每一个函数都包括两个属性lengthprototype

length属性中,将返回参数的个数。如:

function colors(color1,color2){
    var array = [color1,color2];
    document.write(array.join("/"))
}
colors("red","blue");
document.write(" " + colors.length + "个参数"); //red/blue 2个参数

又如:

function toStr(){
        var result = "";
        for (var i = 0; i < arguments.length; i ++){
            result += arguments[i].toString() + " ";
        }
        document.write(result);
        document.write(" " + arguments.length + "个参数" + "<br/>");
        document.write(" " + arguments.callee.length + "个函数希冀参数");
}
toStr(321,32,43243,432,3213);
    
/*
321 32 43243 432 3213 5个参数
0个函数希冀参数    
*/

prototype属性。这个属性是保留它们一切实例要领的真正地点。在建立自定义援用范例以及完成继续时,这个属性是异常重要的(今后再零丁议论)。别的,在ECMAScript 5 中,这个属性不可枚举(不能用for-in)。重要的两个非继续要领有apply()call();这两个要领的用处都是在特定的作用域中挪用函数。

apply()要领吸收两个参数:一个是在个中运转函数的作用域,另一个是参数数组。第二个参数能够是Array 的实例,也能够是arguments 对象。如:

function sum(x,y){
    document.write(x.toString() + y.toString());
}

function plus(){
    return sum.apply(this,arguments);
}

plus(321,"fff");

下面这个则是Array 的实例:

function sum(x,y){
    document.write(x.toString() + y.toString());
}

function plus(a,b){
    return sum.apply(this,[a,b]);
}

plus(321,"fff"); 

call()要领与前者的作用雷同,区分在于吸收参数的体式格局差别。第二个参数必需一个个枚举出来。以下:

function sum(x,y){
    document.write(x.toString() + y.toString());
}

function plus(a,b){
    return sum.call(this,a,b);
}

plus(321,"fff");

上面例子中plus(a,b) 不能写成plus();call(this,a,b)不能写成call(this,arguments)call(this,[a,b])

高能!!!

高能!!!

事实上,apply()call()真正有价值的用处是扩大函数的作用域。如:

var child = {
    name: "Oliver",
    age: 18
}
var adult = {
    name: "Troy",
    age: 24
}

function showName(){
    document.write(this.name);
}

showName.call(adult); //Troy
showName.call(child); //Oliver

运用上面这两个要领来扩大作用域的最大优点就是对象不须要与要领又任何耦合关联。

ECMAScript 5 还定义了一个要领:bind()。this 的值会被绑定到传给bind()函数的值。如:

var child = {
    name: "Oliver",
    age: 18
}
var adult = {
    name: "Troy",
    age: 24
}

function showName(){
    document.write(this.name);
}

var newFunc = showName.bind(child);
newFunc(); //Oliver
    原文作者:JS菌
    原文地址: https://segmentfault.com/a/1190000004006607
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞