函数对象

javascript中函数就是对象,对象字面值产生的对象连接到Object.prototype,函数对象连接到Function.prototype(Function.prototype也连接到Object.prototype)。函数创建时,附加两个隐藏属性,函数上下文和实现函数的代码。函数和对象的不同之处是函数多一个“调用”属性。

函数字面值

函数可以保存在变量中,函数名可以省略。

函数可以嵌套定义,内部的函数可以访问父函数的参数和变量,内部定义的函数包含到父函数上下文的连接,这被称为闭包。

方法调用模式

函数属于一个对象时,这个函数叫做这个对象的方法,方法调用时,还收到两个附加的参数,this和arguments,this指向方法的所属对象,也就是说方法调用时this绑定到其所属对象,arguments包含传入的参数,传入的参数过少,未定义的参数初始化为undefined,过多会自动忽略。

this的用法例子:

var student = {
    "age" : 18,
    "sayhello" : function()
    {
        console.log("I am " + this.age);
    }
};

student.sayhello();

函数调用模式

函数不属于某个对象时,其this被绑定到全局对象,这里javascript语言上就出了个bug,内部函数不属于任何对象,其this被绑定到了全局对象,而实际上显然应该绑定到外部函数的this。解决方法是外部函数定义一个that变量指向this,内部函数使用that。

var student = {
    "age" : 18,
    "sayhello" : function()
    {
        var that = this;
        inner_sayhello();
        function inner_sayhello()
        {
            console.log("I am " + that.age);
        }
    }
};

构造器调用模式

javascript是基于原型的面向对象语言,实际上不应该有构造器的概念,但偏离了主流语言的风格,因此也提供了构造器的概念。

在一个函数前用new调用,将会创建一个连接到该函数prototype成员的新对象,this会被绑定到新对象上。约定这类函数以大写字母开头,像Java的类定义一样。不推荐使用这种构造方式。

function Student(name)
{
    this.name = name;
}
Student.prototype.sayhello = function()
{
    console.log(this.name);
};

apply调用模式

函数也是对象,所以也有方法,apply方法可以手动给函数绑定this和参数数组。

function add(a, b)
{
    return a + b;
}
var result = add.apply(null, [1, 2]);

函数参数

由于函数参数实际上是通过arguments数组(实际上不是数组,而是array-like,包含length属性)传递给函数的,所以可以编写一个无需指定参数个数的函数。例子:

function add()
{
    var sum = 0;
    for(i = 0; i < arguments.length; i++)
    {
        sum += arguments[i];
    }
    return sum;
}

函数返回

return指示进行返回,如果没有指定返回值,返回undefined,使用new时,函数返回值是this。

异常

异常可以中断函数执行,throw抛出一个异常对象,通常应该包含name和message属性,用于说明异常类型和报错信息,也可以根据需求添加其他属性。

try
{
    throw {
        "name" : "error name",
        "message" : "error message"
    };
}
catch(err)
{
    console.log(err.name);
    console.log(err.message);
}

基本类型扩充功能

javascript可以对语言的基本类型扩充功能,上一章的给Object.property添加create()函数就是一个例子。

作用域

Javascript并不支持块级作用域,函数区分作用域。

闭包

内层函数可以直接访问外层函数的变量,而不是将其复制。即使外层函数已经返回了,而内层函数还未执行完,那么就可能保留着一些变量供内层函数调用。例子:

function out_func()
{
    var count = 0;
    function in_func()
    {
        count++;
        console.log(count);
        setTimeout(in_func, 500);
    }
    setTimeout(in_func, 500);
    return "out_func returned";
}

利用闭包实现隐藏

使用闭包可以避免全局变量,把一些信息隐藏到内层函数中,避免被修改。

链式调用

让一个方法返回this可以实现链式调用,例子:

var tom = {
    "age" : 10,
    "growup" : function()
    {
        this.age++;
        return this;
    }
};
tom.growup().growup().growup();
作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。
Copyright © 2017-2024 Gacfox All Rights Reserved.
Build with NextJS | Sitemap