JavaScript红宝书笔记(七)---Function类型

1.函数其实是对象。每一个函数都是 Function 类型的实例,并且都与其余引用类型同样具备属性和方法数组

2.因为函数名仅仅是指向函数的指针,所以函数名与包含对象指针的其余变量没有什么不一样app

function sum(num1, num2){
    return num1 + num2;
}
alert(sum(10,10)); //20
var anotherSum = sum;
alert(anotherSum(10,10)); //20
sum = null;
alert(anotherSum(10,10)); //20

3.ECMAScript中函数没有重载函数

4.函数声明和函数表达式的区别:解析器会率先读取函数声明,并使其在执行任何代码以前可用(能够访问);至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正被解释执行this

alert(sum(10,10));
function sum(num1, num2){
    return num1 + num2;
}                              //函数声明提高,正常执行

alert(sum(10,10));
var sum = function(num1, num2){
    return num1 + num2;
};                            //报错

5.做为值得函数:不只能够像传递参数同样把一个函数传递给另外一个函数,并且能够将一个函数做为另外一个函数的结果返回;仅使用函数名能够访问函数的指针而不执行函数。prototype

function add10(num){
    return num + 10;
}
var result1 = callSomeFunction(add10, 10);
alert(result1); //20

6.函数内部属性arguments指针

arguments它是一个类数组对象,包含着传入函数中的全部参数,它还包含一个属性交callee,该属性是一个指针,指向拥有这个 arguments 对象的函数。callee属性能够用来解耦合。code

function factorial(num){
if (num <=1) {
    return 1;
} else {
    return num * factorial(num-1)        //利用factorial函数名回调递归
    }
}

这样作法若是以后factorial赋值给别的变量,而后又从新赋值一个函数给factorial。那么别的变量并不会调用到本来的递归函数,而是调用到factorial新赋值的函数。因此须要消除这种紧耦合。对象

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

var trueFactorial = factorial;

factorial = function(){
    return 0;
};

alert(trueFactorial(5)); //120
alert(factorial(5)); //0

7.函数内部属性this
this引用的是函数据以执行的环境对象——或者也能够说是 this 值继承

window.color = "red";
var o = { color: "blue" };
function sayColor(){
    alert(this.color);
}
sayColor(); //"red"
o.sayColor = sayColor;
o.sayColor(); //"blue"

ps:函数的名字仅仅是一个包含指针的变量而已。所以,即便是在不一样的环境中执行,全局的sayColor()函数与o.sayColor()函数指向的仍然是同一个函数。递归

8.函数都包含的属性与length和protoType。
length是函数接收的命名参数个数;
protoType是保存他们全部实例方法的真正所在,例如valueOf(),toString(),只不过是经过各自对象的实例访问。另外,prototype 属性是不可枚举的,所以使用 for-in 没法发现。

9.每一个函数都包含两个非继承而来的方法:apply()和 call()。这两个方法的用途都是在特定的做用域中调用函数
apply()方法接收两个参数:一个是在其中运行函数的做用域,另外一个是参数数组

function sum(num1, num2){
    return num1 + num2;
}
function callSum1(num1, num2){
    return sum.apply(this, arguments); // 传入 arguments 对象
}
function callSum2(num1, num2){
    return sum.apply(this, [num1, num2]); // 传入数组
}
alert(callSum1(10,10)); //20
alert(callSum2(10,10)); //20

call()方法与 apply()方法的做用相同,它们的区别仅在于接收参数的方式不一样。传递给函数的参数必须逐个列举出来。

function sum(num1, num2){
    return num1 + num2;
}
function callSum(num1, num2){
    return sum.call(this, num1, num2);
}
alert(callSum(10,10)); //20

10.传递参数并不是 apply()和 call()真正的用武之地;它们真正强大的地方是可以扩充函数赖以运行的做用域

window.color = "red";
var o = { color: "blue" };
function sayColor(){
    alert(this.color);
}
sayColor(); //red
sayColor.call(this); //red
sayColor.call(window); //red
sayColor.call(o); //blue

使用 call()(或 apply())来扩充做用域的最大好处,就是对象不须要与方法有任何耦合关系。

相关文章
相关标签/搜索