专栏首页星回的实验室js重修课[四]:函数

js重修课[四]:函数

最近学习效率比较低下,一定是春天到了的缘故……

函数这一章也是比较重要的一章。js里的Function是一个特殊的对象。

函数定义

函数有两种定义方法:定义表达式如var f = function(){};和声明语句如function f(){}。须知在变量提前这一现象中,声明语句可被提前,而定义表达式虽然声明语句被提前,但赋值并未被提前,因此在表达式前调用该函数会得到undefined。函数声明语句不能出现在循环、条件判断、或者try/catch/finally以及with语句中

函数调用

函数调用有4种方式:

  • 作为函数
  • 作为方法
  • 作为构造函数
  • 通过call()或apply()间接调用

函数调用f(1);一类调用方式,这类方法的this处于全局环境下,在非严格模式下为全局对象,严格模式下为undefined。

方法调用即对一个对象内的函数的调用,如a.sort();。在放大调用中,this指针引用调用该方法的对象。之前一直没有注意的一点是:this和变量不同,它不像变量有作用域的限制。this的引用只与函数的调用方式有关,而与外层函数的上下文无关。只要函数作为普通函数调用,不论嵌套在哪,this的值不是全局对象就是undefined;而只要函数作为方法调用,this的值就是调用它的对象。一般在嵌套函数中利用变量的作用域来保存this的值,如下:

var o = {
    m: function() {
        var self = this;
        function f() {
            console.log(this === o);  //"false": 此时this值为全局变量或undefined
            console.log(self === o);  //"true"
        }
    }
}

构造函数即使用new关键字调用函数。在前一章关于对象继承的说明中说过,这种调用方式会创建一个新的空对象,令其继承构造函数的prototype属性,并将新对象用作其调用上下文。不论它是函数调用还是方法调用,内部的this指针都指向新对象,而不是调用该方法的对象

间接调用即使用call()和apply(),将函数上下文显示传递进去。如f.call(o);,相当于使用对象o调用函数f()。call()和apply()的区别在于前者接受不定参数,分别为调用函数和参数列表,如f.call(o, 1, 2);,而apply()接受的是调用函数和参数数组。bind()方法是ECMAScript 5新增的方法,可以更便捷地绑定调用函数上下文。使用方法如f.bind(o);,即用o调用f()。在未实现ECMAScript 5的一种兼容写法如下:

function bind(f, o) {
    if (f.bind) return f.bind(o);   //若bind方法存在,返回其引用
    else return function() {
        f.apply(o, arguments);      //若不存在,用apply()模拟
    }
}

闭包

这也几乎是逢js必谈的一个专题了,说得太多,只是记录一些概要。

简言之,闭包就是指函数体将各自内部的变量保存在自有作用域内的一种现象。在js中,函数若是没有定义嵌套函数,那么在返回的时候引用清零,函数内的变量就会被回收。而若定义了嵌套函数,并将其作为返回值存于某个属性中,保持了引用,这个嵌套函数所绑定的变量就不会被当作垃圾回收。简单的实现如下:

function counter() {
    var x = 0;
    return {
        count: function() { return x++; },
        reset: function() { x = 0; }
    };
}

var a = counter(), b = counter();
a.count(); // => 0
b.count(); // => 0:a和b将独立计数
a.reset(); // => 0:重置

使用闭包可是共享私有变量,实现诸如单例一类的功能。隐患也很显然:处理不当容易造成内存泄露。

函数式编程

嗯,像Lisp和Haskell那样写js,听起来是挺牛逼的……总之是利用函数值传递一系列技巧实现,示例如下,不知以后能否有更多应用:

function compose(f, g) {
  var self = this;
  return function() {
    return f.call(this, g.apply(this, arguments));
  }
}

var square = function(x) { return x*x; };
var sum = function(x, y) { return x + y };
var squareofsum = compose(square, sum);
console.log(squareofsum(2, 3));  // => 25

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Angularjs的回调

    $q.reject() 方法是在你捕捉异常之后,又要把这个异常在回调链中传下去时使用:

    星回
  • nodejs实现简单的自动约车

    最近约车真是越来越难了,网上约车经常车位刚放出来便已空空如也。突然回想起之前学车时教练反复提到的约车软件,去淘宝上一查:我去,卖出去一千多份了!还能约到车那就是...

    星回
  • golang建立MongoDB连接池

    最近用go语言重构之前用python草草搭建的推荐引擎,语言杂食确实很难受,不过不得不说,在饱受弱类型脚本语言的摧残之后重新用回强类型语言,轻微强迫症的我居然还...

    星回
  • 深入理解JavaScript系列(37):设计模式之享元模式

    享元模式(Flyweight),运行共享技术有效地支持大量细粒度的对象,避免大量拥有相同内容的小类的开销(如耗费内存),使大家共享一个类(元类)。

    用户4962466
  • 【Golang语言社区--H5编程】smoke.js

    大家好,我是社区主编彬哥,今天给大家带来的H5游戏编程中,烟雾特效的js库; 源码如下 var smokemachine = function (c...

    李海彬
  • SAP IBASE logic of pt_equiindx

    版权声明:署名,允许他人基于本文进行创作,且必须基于与原先许可协议相同的许可协议分发本文 (Creative Commons)

    Jerry Wang
  • JavaScript 10分钟入门

    简介 JavaScript是一门面向对象的动态语言,他一般用来处理以下任务: 1、修饰网页 生成HTML和CSS 生成动态HTML内容 生成一些特效 2、提供...

    前朝楚水
  • JavaScript 常用功能总结

    小编吐血整理加上翻译,太辛苦了~求赞! 本文主要总结了JavaScript 常用功能总结,如一些常用的JS 对象,基本数据结构,功能函数等,还有一些常用的设计模...

    葡萄城控件
  • 实用的JS代码段(表单篇)

    整理了下比较实用的Javascript代码段,完整的代码参考 1 多个window.onload方法   由于onload方法时在页面加载完成后,自动调用...

    用户1154259
  • 不同浏览器input file样式不一样

    2、判断浏览器类型,如果是非IE,则将页面上的input 设置为近乎透明,然后将图片放在上面。

    一笠风雨任生平

扫码关注云+社区

领取腾讯云代金券