Javascript 元编程初探 [1]

引子

元编程会有以下的定义:

一种计算机顺序的编写体式格局,它能够将别的顺序(或许其自身)作为数据举行编写和操纵,或许在编译时做一部份事情,在运转的时刻做别的一部份事情。

在这里讲到的很多或许只和顺序关于事情机制的操纵有关,然则作为初探或许也就足够了。 鉴于我也是边学边写的这篇文章,如果有错误的地方,还请指出。

建立带有默许参数的函数

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,也是算对本身的一种推动吧,纪录一些所进修的学问,分享一写进修的心得。

    原文作者:__SSSamuel
    原文地址: https://segmentfault.com/a/1190000000337417
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞