zoukankan      html  css  js  c++  java
  • 【js语言精粹】第四章 函数

    在JavaScript中一共有四种调用模式:方法调用模式、函数调用模式、构造器调用模式和apply调用模式。这些模式在如何初始化关键参数this上存在差异。

    1. 方法调用模式

    当一个函数被保存为对象的一个属性时,我们称它为一个方法。当一个方法被调用时,this被绑定到该对象。如:

    var myObject = {
        value:0;
        increment:function(inc){
            this.value += typeof inc === 'number' ? inc : 1;
        }
    };
    myObject.increment(2)
    document.writeln(myObject.value); // 3

    方法可以使用this去访问对象,所以它能从对象中取值或修改该对象。this 到对象的绑定发生在调用的时候,“迟绑定”

    2. 函数调用模式

    当一个函数并非一个对象的属性时,那么它被当作一个函数来调用:

    var sum = add(3,4);  // sum 的值为7

    当函数以此模式调用时,this被绑定到全局对象。这是语言设计上的一个错误。解决的方法是定义一个变量并给它赋值为this。

    myObject.double = function(){
        var that = this;
        this.value = 6;
        var helper = function(){
            console.log(that.value);
        }
        helper();
    }
    myObject.double(); // 6

    3. 构造器调用模式

    如果在一个函数前面带上new来调用,那么将创建一个隐藏连接到该函数的prototye成员的新对象,同时this将会被绑定到那个新对象上。

    new 前缀也会改变return语句的行为。?

    var Quo = function(string){
        this.status = string;
    }
    Quo.prototype.get_status = function(){
        return this.status;
    }
    var myQuo = new Quo("confused");
    console.log(myQuo.get_status()); // confused

    4. Apply调用模式

    因为JavaScript是一门函数式的面向对象编程语言,所以函数可以拥有方法。

    apply方法接收两个参数。第一个是将被绑定给this的值。第二个就是一个参数数组。

    var Quo = function(string){
        this.status = string;
    }
    Quo.prototype.get_status = function(){
        return this.status;
    }
    var myQuo = new Quo("confused");
    
    // 自己乱写的add方法
    function add(){
        var sum = 0;
        Array.prototype.forEach.call(arguments,function(value,key,array){
                sum+=value;
            });
        return sum;
    }
    var array = [3,4,5];
    var sum = add.apply(null,array); // sum值为7
    console.log(sum);
    
    var statusObject = {
        status:'A-OK'
    }
    var status = Quo.prototype.get_status.apply(statusObject);
    console.log(status); // A-OK

     注:new 前缀也会改变return语句的行为。

    如果函数以在前面加上new前缀的方式来调用,且返回值不是一个对象,则返回this(该新对象)。返回值是对象是则返回该对象!!!!!

    1.给类型增加方法

    通过Function.prototype增加方法来使得该方法对所有函数可用

    Function.prototype.method = function(name,func){
        this.prototype[name] = func;
        return this;
    }

    给Number.prototype添加一个integer方法来根据数字的正负来判断使用Math.ceiling还是Math.floor

    Number.method('integer',function(){
        return Math[this < 0 ? 'ceiling' : 'floor'](this);
    });

    给String.prototype添加trim方法来移除字符串的末端空格

    String.method('trim',function(){
        return this.replace(/s+|s+$/g,'');
    });
    console.log('"'+" n ear ".trim()+''); // n ear

     记忆

    函数可以用对象去记住先前的操作,从而能避免无谓的运算。

    var memoizer = function(memo,fundamental){
        var shell = function(n){
            var result = memo[n];
            if(typeof result !== 'number'){
                result = fundamental(shell,n)
                memo[n] = result;
            }
            return result;
        };
        return shell;
    }
    var fib = memoizer([0,1],function(shell,n){
        return shell(n-1)+shell(n-2);
    });
    var res = fib(30);console.log(res);

    套用 柯里化

    Function.prototype.method = function(name,func){
        this.prototype[name] = func;
        return this;
    }
    function add(){
        var sum = 0;
        console.log(arguments);
        Array.prototype.forEach.call(arguments,function(value,key,array){
                sum+=value;
            });
        return sum;
    }
    Function.method('curry',function(){
        var slice = Array.prototype.slice,
            args = slice.apply(arguments),
            that = this;
        return function(){
            return that.apply(null,args.concat(slice.apply(arguments))); // 如果是调用非内置的方法(slice,forEach..)时一定要传个对象
        }
    });
    var res = add.curry(1)(2,3,4);
    console.log(res); // 10
  • 相关阅读:
    PHP $_POST 变量
    PHP $_GET 变量
    PHP 完整表单实例
    PHP 表单
    PHP 表单
    PHP 表单验证
    00_前情回顾
    18_今日回顾
    VMware 12PRO安装Mac OS X 10.10.5
    05_传智播客iOS视频教程_第一个OC程序
  • 原文地址:https://www.cnblogs.com/fjl-vxee/p/8626624.html
Copyright © 2011-2022 走看看