码迷,mamicode.com
首页 > 编程语言 > 详细

Javascript 函数总结

时间:2015-06-30 17:55:20      阅读:125      评论:0      收藏:0      [点我收藏+]

标签:

函数的定义

函数名称只能包含字母、数字、下划线或$,且不能以数字开头。定义时可用函数定义表达式或者函数声明语句。

var f = function fact(x){}

函数定义表达式包含名称,名称将作为函数的局部变量,在函数内部使用,代指函数。

函数声明语句不是真正的语句,不能出现在循环、条件、try/catch/finally以及with语句中;声明语句置于在不会执行到的位置仍可被整个作用域可访问,可在被定义代码之前使用。定义表达式的变量声明被提前了,但是对变量赋值不会提前,函数在被定义之前无法使用,否则调用时会出现错误:"TypeError: undefined is not a function"

return语句没有一个与之相关的表达式,则它返回undefined值;如果一个函数不包含return语句,那它只执行函数体内语句,并返回undefined给调用者;没有返回值的函数,有时称为过程。

函数执行

函数执行的几种方式,当作函数、方法、构造函数、间接调用。如果构造函数没有形参,可以省略实参列表和圆括号,调用函数传实参有间隔时,可用null或undefined占位符替代空白的参数。

function MyClass(name) {
    this.name = name;
    return name;  // 构造函数的返回值?
}

var obj1 = new MyClass(‘foo‘);// MyClass对象
var obj2 = MyClass(‘foo‘);// ‘foo’
var obj3 = new MyClass({});// {}
var obj4 = MyClass({});// {}

实参对象

实参对象是类数组对象,可用arguments.callee递归调用,如果你把参数命名为arguments,那么这个参数就会覆盖它原有的特殊变量。

函数的形参和实参

定义的函数括号内靠后面的形参没传入相应的实参,则默认值为undefined,有人利用这个,隐式定义函数内部的局部变量。函数传入参数的校验及抛出错误,函数中实参传入的是引用,函数内部对其操作,对外部是可见的。

// 函数传参引用
var oo = {
    x: 1, y: 2, get z() {
        return 3;
    }
}

function fns(obj) {
    obj.h = 4;
}

fns(oo);

函数属性、方法

函数也是对象,所以也有属性和方法,函数的length属性,函数形参的个数。

apply方法的第二个参数可以是数组或类数组对象。

bind方法是ES5中新增,将函数“绑定至”对象并传入一部分参数,传入的实参放在完整实参列表的左侧。

/**
 * ES5.0支持bind函数,ES3.0不支持bind,这里在ES3中模拟实现,能应用于大部分场景,
 * 如有问题,欢迎一起探讨
 * https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
 */
Function.prototype.bind || (Function.prototype.bind = function (that) {
    var target = this;
    // If IsCallable(func) is false, throw a TypeError exception.
    // 通过call、apply调用时,校验传入的上下文
    if (typeof target !== ‘function‘) {
        throw new TypeError(‘Bind must be called on a function‘);
    }

    var boundArgs = slice.call(arguments, 1);

    function bound() {
        // 返回的bind函数被当构造函数
        if (this instanceof bound) {
            var self = createObject(target.prototype);
            var result = target.apply(
                self,
                boundArgs.concat(slice.call(arguments)));
            // Object(result) === result 判断调用返回是不是对象
            return Object(result) === result ? result : self;
        }
            // 返回的bind函数以一般函数形式调用
        else {
            return target.apply(
                that,
                boundArgs.concat(slice.call(arguments)));
        }
    }

    // NOTICE: The function.length is not writable.
    bound.length = Math.max(target.length - boundArgs.length, 0);
    return bound;
});

高阶函数

如果函数作为参数或返回值使用时,就称为高阶函数。

作为命名空间的函数

函数命名空间暴露接口有以下几种方法

var mylib = (function (global) {
    function log(msg) {
        console.log(msg);
    }
    log1 = log;  // 法一:利用没有var的变量声明的默认行为,在log1成为全局变量(不推荐)
    global.log2 = log;  // 法二:直接在全局对象上添加log2属性,赋值为log函数(推荐)
    return {  // 法三:通过匿名函数返回值得到一系列接口函数集合对象,赋值给全局变量mylib(推荐)
        log: log
    };
}(window));

自更新函数

function selfUpdate() {
    window.selfUpdate = function () {
        alert(‘second run!‘);
    };

    alert(‘first run!‘);
}

selfUpdate(); // first run!
selfUpdate(); // second run!

这种函数可以用于只运行一次的逻辑,在第一次运行之后就整个替换成一段新的逻辑。

函数书写规范

函数参数定义的几种注释

/*,...*/
AP.reduce || (AP.reduce = function(fn /*, initial*/) {
    getPropertyNames(o,/*optional*/a) // /*optional*/表示参数可选
    function arraycopy(/*array */ from,/*index*/from_start){};
}

具有记忆功能的函数

/**
 *  记忆函数
 */
function memorize(f) {
    var cache = {};
    return function () {
        var key = arguments.length + ‘‘ + Array.prototype.join.call(arguments, ‘,‘);
        if (!(key in cache))
            cache[key] = f.apply(null, arguments);
        return cache[key];
    }
}

 

Javascript 函数总结

标签:

原文地址:http://www.cnblogs.com/Crow00/p/4610936.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!