javascript语言精粹之javascript函数

发布时间:2019-09-12编辑:脚本学堂
本文介绍了javascript语言精粹中有关javascript函数的用法,有需要的朋友参考下。

以下代码要用到之前博客中的代码,在执行时请将其中的代码引入,否则报错。
 

复制代码 代码示例:

console.log('*************调用(方法调用模式、函数调用模式、构造子调用模式和Apply调用模式)'); 
 
console.log('第一种模式:方法调用模式'); 
//当一个函数被保存为对象的一个属性时,我们称它为一个方法, 
//如果调用表达式包含一个提取属性的动作(即包含一个 . 点表达式或[subscript]下标表达式), 
//那么它就是被当做一个方法来调用 。当一个方法被调用时,this被绑定到该对象。 
myObject = { 
    value : 0, 
    increment : function(inc){ 
        this.value += typeof inc === 'number' ? inc : 1; 
    } 
}; 
myObject.increment(); 
console.log(myObject.value); 
myObject.increment(5); 
console.log(myObject.value); 
 
console.log('第二种模式:函数调用模式'); 
//当一个函数并非一个对象的属性时,那么它就是被当做一个函数来调用。 
//在内部函数被调用的时,this应该仍然绑定到外部函数的this变量。 
//解决办法是在外部函数定义一个变量并给它赋值为this,那么内部函数就可以通过那个变量访问到this。 
//按照约定,把那个变量命名为that。 
myObject.double = function(){ 
    var that = this; //解决方案 
    var helper = function(){ 
        console.log("为赋值给that变量前:",this); 
        console.log("为赋值给that变量后:",that); 
    }; 
    helper(); //以函数的形式调用 helper 
}; 
// 以方法的形式调用 
myObject.double(); 
 
console.log('第三种模式:构造器调用模式'); 
var Quo = function(string){ 
    console.log(this); 
    this.status = string; 
}; 
Quo.prototype.get_status = function(){ 
    return this.status; 
}; 
//在使用new时,this绑定具体实例 
var myQuo = new Quo('confused'); 
console.log(myQuo.get_status()); 
//不使用new时,this绑定window 
var myQuo2 = Quo('con'); 
console.log(myQuo2 && myQuo2.status); 
console.log(window.status); 
 
console.log('第四种模式:Apply调用模式'); 
var statuObject = { 
        status : 'A-OK' 
}; 
console.log(Quo.prototype.get_status.apply(statuObject)); 
 
 
console.log('*************异常'); 
var add = function(a,b){ 
    if(typeof a !== 'number' || typeof b !== 'number'){ 
        throw{ 
            name : 'typeError', 
            message : 'add need number' 
        }; 
    } 
    return a+b; 
}; 
(function(){ 
    try{ 
        console.log(add('d',2)); 
    }catch(e){ 
        document.write(e.name); 
        console.log(e.name+':'+e.message); 
    } 
})(); 
 
console.log('*************扩充类型的功能'); 
Function.prototype.method = function(name,func){ 
    //基本类型的原型是公用结构,所以在类库混用时务必小心。在确定没有该方法时才添加它。 
    if(!this.prototype[name]){ 
        this.prototype[name] = func; 
    } 
    return this; 
}; 
 
Number.method('integer',function(){ 
    return Math[this < 0 ? 'ceil' : 'floor'](this); 
}); 
console.log((-10/3).integer()); 
//通过method方法构造string转换成int函数 
String.method('toInteger',function(){ 
    var newStr = ''; 
    var str = this || ''; 
    for(var i=0;i<str.length;i++){ 
        if(str.charCodeAt(i) < 58){ 
            newStr += str.charAt(i); 
        } 
    } 
    return parseInt(newStr) || ''; 
}); 
console.log('2222dd33'.toInteger()); 

console.log("*************闭包(看页面的渐变效果)"); 
var fade = function(node){ 
    var level = 1; 
    var step = function(){ 
        var hex = level.toString(16); 
        node.style.background = '#' + hex + hex + hex + hex + hex + hex; 
        if(level < 15){ 
            level++; 
            setTimeout(step,40); 
        }else{ 
//          console.log("结束"); 
        } 
    }; 
    setTimeout(step,40); 
}; 
fade(document.body); 
// 构造一个函数,用错误的方式给一个数组中的节点设置时间处理程序。 
//当点击一个节点时,按照预期,应该弹出一个对话框显示节点的序号, 
//但它总是会显示节点的数目。 
 
/*
    var add_the_handlers = function(nodes){
        var i;
        for(i = 0;i<nodes.length;i++){
            nodes[i].onclick = function(e){
                alert(i);
            };
        }
    };
*/ 
 
//改良后的例子 
var add_the_handlers = function(nodes){ 
    var i; 
    var helper = function(i){ 
        return function(e){ 
            alert(i); 
        }; 
    }; 
    for(i = 0;i<nodes.length;i++){ 
        nodes[i].onclick = helper(i); 
    } 
}; 
//(这个我也不是太清楚是怎么回事,有懂的大牛们希望指点) 
 
console.log("*************模块"); 
//模块模式的一般形式是:一个定义了私有变量和函数的函数; 
//利用闭包创建可以访问的私有变量和函数的特权函数; 
//最后返回这个特权函,或者把它们保存到一个可以访问的地方。 
String.method('deentityify',function(){ 
    var entity = { 
        quot : '"', 
        lt : '<', 
        gt : '>' 
    }; 
    return function(){ 
        return this.replace(/&([^&]+);/g,function(a,b,c){ 
            //a 表示/&([^&;]+);/g匹配的结果,b表示([^&;]+)匹配的结果,c表示的字符串 
            console.log(a,b,c); 
            var r = entity[b]; 
            return typeof r === 'string' ? r : a; 
        }); 
    }; 
}()); 
console.log('&lt;&quot;&gt;'.deentityify()); 
var serial_maker = function(){ 
    var prefix = ''; 
    var seq = 0; 
    return { 
        set_prefix : function(p){ 
            prefix = String(p); 
        }, 
        set_seq : function(s){ 
            seq = s || seq; 
        }, 
        getsym : function(){ 
            var result = prefix +seq; 
            seq ++; 
            return result; 
        } 
    }; 
}; 
var seqer = serial_maker(); 
seqer.set_prefix('T'); 
seqer.set_seq(1024); 
console.log(seqer.getsym()); 
seqer.set_prefix('D'); 
seqer.set_seq(); 
console.log(seqer.getsym()); 
//seqer.getsym = function(){ 
//  return prefix; 
//}; 
//console.log(seqer.getsym());  //Uncaught ReferenceError: prefix is not defined 
 
console.log("*************级联"); 
//在没有返回值的方法中加入返回this,就可以启动级联。在级联中,我们可以在单独一条语句中一次调用一个对象的很多方法。 
var user_maker = function(){ 
    var user = { 
        name : "truth", 
        sex : "male", 
        age : 24 
    }; 
    return { 
        set_name : function(n){ 
            user.name = n; 
            return this; 
        }, 
        set_sex : function(s){ 
            user.sex = s; 
            return this; 
        }, 
        set_age : function(a){ 
            user.age = a; 
            return this; 
        }, 
        add_user_info : function(key,value){ 
            user[key] = value || ''; 
            return this; 
        }, 
        get :function(){ 
            return user; 
        } 
    }; 
}; 
var u = user_maker(); 
console.log(u.set_name('lee').add_user_info('weight','130kg').get()); 
 
console.log("*************记忆"); 
//函数可以将先前操作的寄过记录在某个对象里,从而避免无谓的重复运算。这种优化被称为记忆。 
//下面的例子就是将算好的值存储在memo数组里减少不必要的重复计算,进而优化。 
//斐波那契数列算法 
var memoizer = function(memo,formula){ 
    var recur = function(n){ 
        var result = memo[n]; 
        if(typeof result !== 'number'){ 
            result = formula(recur,n); 
            memo[n] = result; 
        }else{ 
            console.log(memo[n]); 
        } 
        return result; 
    }; 
    return recur; 
}; 
var fibonacci = memoizer([0,1],function(recur,n){ 
    return recur(n-1)+recur(n-2); 
}); 
console.log(fibonacci(10));