资讯专栏INFORMATION COLUMN

Javascript 元编程初探 [1]

mcterry / 914人阅读

摘要:在这里讲到的很多也许只和程序对于工作机制的操作有关,但是作为初探也许也就足够了。一般情况下还有空字符串都会被判断成。面向特征编程面向特征编程的全称是。

引子

元编程会有如下的定义:

一种计算机程序的编写方式,它可以将其它程序(或者其本身)作为数据进行编写和操作,或者在编译时做一部分工作,在运行的时候做另外一部分工作。

在这里讲到的很多也许只和程序对于工作机制的操作有关,但是作为初探也许也就足够了。 鉴于我也是边学边写的这篇文章,如果有谬误之处,还请指出。

创建带有默认参数的函数
function repeat(func, times) {
    times = (Object.prototype.toString.call(times) === "[object Undefined]")?1:times;
    for(var i = 0; i < times; i++){
        func();
    }
}   

在函数中使用 Object.prototype.toString.call(times) 是为了解决 javascript 判断值为空的问题,使用这种写法才会比较的安全。一般情况下 false, 0, undefined, null 还有 空字符串 都会被判断成 false。

创建自优化的行数

在浏览器的实现上会有许多的不同,有时候就需要使用分支。一般情况下都是监测需要调用的对象或者属性是否存在,进而进行下一步的操作,像下面的一样:

function addEvent(elem, type, func){
    if (document.addEventListener) {
        elem.addEventListener(type, func);
    } else {
        elem.attachEvent(type, func);
    }
}

虽然这段代码可能还有很多其它的问题,但是这段代码每次在执行时都会进行一次判断,然而理论上应该可以做到只在第一次运行的时候进行判断: 当第一次调用的时候,针对特定的浏览器去将自己重写成另外的一个版本

function newAddEvent (elem, type, func) {
    if (document.addEventListener){
        newAddEvent = function(element, type, func){
            element.addEventListener(type, func);
        }
    } else {
        newAddEvent = function(element, type, func){
            element.attachEvent(type, func);
        }
    }
    newAddEvent(elem, type, func);
}

在这个函数中,第一次调用的时候会进行判断支持的方法类型,然后就会替换掉原来函数的内容,最后都会执行新的函数。虽然这个是一个简单的例子,但是可以把它引申并且使用到其它复杂的环境中去,这样就可以提高运行的效率了。

面向特征编程(AOP)

面向特征编程的全称是: Aspect-oriented Programming。面向特征编程本质上就是使用函数执行前后的代码去扩展当前的函数,而不是使用继承的方式去扩展。

在调试一段代码的时候,需要在这个代码被调用的时候写一些日志,包括 传入的参数以及函数调用之后的返回值,并且这样不会影响到函数的正常执行 ,我们可以这样写:

Bar = {
    foo: function(){ ... }
};

Bar.foo = Bar.foo.debug(function(original, args){
        var _r;
        console.log(args);
        _r = original(args);
        console.log(_r);
        return _r;
});

(注: 此处的参数部分简略写了,不要在意这些细节~) 我在这里扩展了Function的prototype的方法,将原始函数作为第一个参数传入,其实还可以稍加改变,在新的一个函数上进行这种包装。 接下来我们来看看debug的实现:

Function.prototype.debug = function(debugger) {
    var _selfMethod = this; // 原始方法的引用
    return function(){
        var args = [];
        for (var i = 0, argsLength = arguments.length; i < argsLength; i++) {
            args.push(arguments[i]);
        }
        return debugger.apply(this, [_selfMethod.bind(this)].concat(args));
    }
};

这段代码首先保存了原始函数的一个引用,然后将参数传入debugger并使用apply执行。


第一次在segmentFault写blog,也是算对自己的一种鞭策吧,记录一些所学习的知识,分享一写学习的心得。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/77955.html

相关文章

  • WebGL 初探

    摘要:下面是顶点及片元着色器程序,用字符串表示,它将直接运行在浏览器之上。最后,使用将和着色器连接。创建着色器对象创建编程对象赋值已创建的着色器对象连接编程对象检查链接结果链接程序失败使用可用着色器程序这一步主要使用方法告诉使用程序。 该文章于一天前发表在 github,若有问题可提至 github。 目前,我们有很多方案可以快速的接触到 WebGL 并绘制复杂的图形,但最后发现我们忽视了很...

    whjin 评论0 收藏0
  • 函数式编程初探

    摘要:函数式编程是一种以函数为基础的编程方式和代码组织方式,从程序员的思路上来说,就是将程序拆分并抽象成多个函数,再组装回去。在这门语言中,函数是一等公民,函数可以作为函数的参数,函数也可以返回一个函数,因此适合函数式编程风格。 函数式编程 ( Functional Programming ) 是一种以函数为基础的编程方式和代码组织方式,从程序员的思路上来说,就是将程序拆分并抽象成多个函数,...

    oogh 评论0 收藏0
  • Python Metaclass 初探

    摘要:以我们的程序为例,就是以为产生了一个名为的新类型,改类型的实现由给出,而就包含了通过返回的这个方法。从中找到这些类并一一执行测试。 先以一个大牛的一段关于Python Metapgramming的著名的话来做开头: Metaclasses are deeper magic than 99% of users should ever worry about. If you wonder ...

    nidaye 评论0 收藏0
  • [python] 初探'函数式编程'

    摘要:前言继续向下看廖大教程,看到了函数式编程这一节,当时是觉得没啥用直接跳过了,这次准备要仔细看一遍了,并记录下一些心得。 前言 继续向下看廖大教程,看到了函数式编程这一节,当时是觉得没啥用直接跳过了,这次准备要仔细看一遍了,并记录下一些心得。 函数式编程 上学期有上一门叫 人工智能 的课,老师强行要我们学了一个叫做 prolog 的语言,哇那感觉确实难受,思维方式完全和之前学过的不一样,...

    xcc3641 评论0 收藏0
  • 初探Linux---Linux文件系统概览

    摘要:六文件类型与目录结构支持很多文件类型,其中非常重要的文件类型有普通文件,目录文件,链接文件,设备文件,管道文件,套接字文件等。套接字文件套接字文件被用于网络进程之间的通信,既可以使台不同的机器进行通信,也可以用于本机的网络程序。一、Linux简介类Unix系统: Linux是一种自由、开放源码的类似Unix的操作系统Linux内核: 严格来说,Linux这个词本身只表示Linux内核Linu...

    Tecode 评论0 收藏0

发表评论

0条评论

mcterry

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<