//函数作为参数
console.log("函数作为参数")

function callSomeFunction(function0, arg0) {
    return function0(arg0);
}

function add10(num) {
    return num + 10;
}
console.log(callSomeFunction(add10, 10));

//函数作为返回值
console.log("\n函数作为返回值")

function createComparisonFuntion(propertyName) {
    return function (obj1, obj2) {
        var value1 = obj1[propertyName]; //注意必须使用方括号索引属性,因为属性名是变量
        var value2 = obj2[propertyName];

        if (value1 < value2) {
            return -1;
        } else if (value1 > value2) {
            return 1;
        } else {
            return 0;
        }
    }
}
var data = [{
    name: "Zachary",
    age: 28
}, {
    name: "Nicholas",
    age: 29
}];
data.sort(createComparisonFuntion("name"));
console.log(data[0].name);
data.sort(createComparisonFuntion("age"));
console.log(data[0].name);

//函数体与函数名解耦:使用arguments.callee表示当前函数
//此外caller表示当前函数的调用函数,如arguments.callee.caller可以访问调用函数
console.log("\n函数体与函数名解耦")

function factorial(num) {
    if (num <= 1) {
        return 1;
    } else {
        return num * arguments.callee(num - 1);
    }
}
var trueFactorial = factorial;
factorial = function () {
    return 0;
};
console.log(factorial(5));
console.log(trueFactorial(5));

//this变量:注意,函数中this是不确定的,函数本身不代表任何环境
console.log("\n函数体与函数名解耦")
var globel0 = new Object();
globel0.color = "red";
var context0 = {
    color: "blue"
};

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

globel0.sayColor = sayColor;
globel0.sayColor();
context0.sayColor = sayColor;
context0.sayColor();

console.log("\n使用call或apply函数扩充作用域"); //bind函数也有类似功能
sayColor.call(globel0);
sayColor.apply(context0);