JS函数的4种调用模式

作者: oldSix_Zhu | 来源:发表于2017-03-08 19:28 被阅读112次

    若有不妥,请多指教
    <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/apply">学习网址推荐</a>

    JS函数的4种调用模式包括:
    1.函数模式
    2.方法模式
    3.构造函数模式
    4.上下文模式(也有叫apply模式)


    1.函数模式

    就是最基本的函数

            function test1() {
                //this指向window全局对象
                console.log(this);
            }
            test1();
    

    2.方法模式

    我们创建一个对象,这个对象有一个函数,那这个函数就叫方法,通过对象调用方法的模式

            var obj2 = {
                test2:function () {
                    //this指向调用这个方法的对象
                    console.log(this);
                }
            }
            obj2.test2();
    

    3.构造函数模式

    构造函数的注意事项:
    1>首字母要大写
    2>构造函数中的this指定的是创建出来的对象
    3>函数默认返回的是创建出来的对象

    3.1构造模式:

            function Star(name,age) {
                this.name = name;
                this.age = age;
                this.sayHello = function () {
                   //this指向使用new创建出来的对象
                    console.log(this.name + 'hi');
                }
            }
            var star = new Star("邱淑贞",18);
            star.sayHello();
    

    3.2工厂模式:
    工厂就是用来模式化生产东西的, 因此如果函数创建对象并返回, 就称该函数为工厂函数

            function Star(name,age) {
                var obj = {
                    name:name,
                    age:age,
                    sayHello:function () {
                        console.log(this.name + 'hi');
                    }
                }
                return obj;
            }
            var star = Star("邱淑贞",18);
            star.sayHello();
    

    或者这种写法

            function Star(name,age) {
                var obj = new Object();
                obj.name = name;
                obj.age = age;
                obj.sayHello = function () {
                    console.log(this.name + 'hi');
                }
                return obj;
            }
            var star = Star("邱淑贞",18);
            star.sayHello();
    

    3.3寄生式构造函数模式:
    提到工厂模式就不得不提寄生式构造函数
    可以看出二者的不同就是调用时一个用new,一个没有用new

            function Star(name,age) {
                var obj = {
                }
                obj.name = name;
                obj.age = age;
                obj.sayHello = function () {
                    console.log(this.name + 'hi');
                }
                return obj;
            }
            var star = new Star("邱淑贞",18);
            star.sayHello();
    

    作用嘛寄生构造函数专门用来为js原生的构造函数扩展新的方法
    假设我们想创建一个具有额外方法的特殊数组
    由于不能直接修改Array构造函数,所以我们可以使用寄生模式

    function SpecialArray() {
        //创建数组
        var array=new Array();
        //添加值  arguments获取的是实参,不是形参,所以SpecialArray()并没有形参接收传递过来的参数
        array.push.apply(array,arguments);
        array.toPipedString=function(){
            return this.join("|");
        }
        return array;
    }
    var colors=new SpecialArray("red","blue","black");
    alert(colors.toPipedString());  //输出:red|blue|black
    

    4.上下文模式

    可以看出,前面三种函数调用模式的最主要区别就是this的指向不同
    而上下文模式最主要的功能就是可以修改this的指向,指定的谁就是谁

    实现方式为:
    1>函数.call(对象,参数1,参数2,参数3,参数4)
    2>函数.apply(对象,数组)
    二者都可以用来改变this的指向为参数的第一个值(对象)

    第一个参数:
    如果传入的是一个对象, 那么就相当于设置该函数中的 this 为参数
    如果不传入参数, 或传入 null undefiend 等, 那么相当于 this 默认为 window

    第二个参数:
    在使用此模式调用的时候, 原函数(方法)可能会带有参数, 那么这个参数使用第二个( 第 n 个 )参数来表示
    call在函数的形参个数确定的情况下使用
    apply在函数的形参个数不确定的情况下使用

    如果是函数调用test(), 那么有点类似于test.apply(window)
    如果是方法调用obj.method(), 那么有点类似于obj.method.apply(obj)

    MDN搜索function.prototype.apply().png

    看一个简单的例子:
    运行结果是打印两次"邱淑贞漂亮等级为:100级"
    而不是王祖贤

            var name = "王祖贤";
            function sayHello(a,b) {
                console.log(this.name + '漂亮等级为:' + (a * b) + '级');
            }
    
            var obj = {
                name:"邱淑贞"
            }
            
            sayHello.apply(obj,[10,10]);
            sayHello.call(obj,10,10);
    

    再看一个快速打印数组中最大值的例子:
    运行结果是打印66

            var arr = [9,12,23,22,11,33,66];
            var max = Math.max.apply(null,arr);
            console.log(max);
    

    再看一个将所有参数用-连接起来的例子:
    运行结果为打印
    0: "66-王祖贤-邱淑贞-覃芳菲-都是大美女-66"
    1: "66+王祖贤+邱淑贞+覃芳菲+都是大美女+66"

            function test() {
                //arguments是所有形参的集合
                //在函数中,使用特殊对象arguments,无需明确指出参数名,就能访问它们
                var str1 = Array.prototype.join.apply(arguments,["-"]);
                var str2 = Array.prototype.join.call(arguments,"+");
                var arr = [str1,str2];
                return arr;
            }
            var arr = test(66,"王祖贤","邱淑贞","覃芳菲","都是大美女",66);
            console.log(arr);
    

    值得注意的是:
    当用call和apply传入的第一个参数为值类型的时候,会将值类型转换成对应的对象(引用类型)然后赋值给this
    当传入的第一个参数为 null或者undefined的时候,会把this赋值为window

            function test() {
                console.log(this);
            }
    
            test.apply(1);          //打印Number
            test.apply("abc");      //打印String
            test.apply(true);       //打印Boolean
            test.apply(undefined);  //打印Window
            test.apply(null);       //打印Window
    

    4.1借用构造函数实现继承:
    运行结果为打印Star {name: "邱淑贞", age: 18}

            function Person(){
                this.name = "邱淑贞";
                this.age = 18;
            }
    
            function Star(){
                var star = this;
                Person.apply(star);
            }
    
            var star = new Star();
            console.log(star);
    

    相关文章

      网友评论

        本文标题:JS函数的4种调用模式

        本文链接:https://www.haomeiwen.com/subject/plzbgttx.html