美文网首页
js里函数调用的四种模式

js里函数调用的四种模式

作者: hanyuntao | 来源:发表于2017-04-29 15:02 被阅读0次

js 里函数调用有4种模式:方法调用、正常函数调用、构造器函数调用、apply/call调用。同时,无论哪种函数调用除了你声明时定义的形参外,还会自动添加2个形参,分别是thisarguments

1.方法调用

这个很好理解,函数是一个对象的属性,比如

var a = {
    v : 0,
    f : function(xx) {
        this.v = xx;
    }
}
a.f(5);

这个时候,上面函数里的 this 就绑定的是这个对象 a。所以this.v 可以取到对象a 的属性 v

2.正常函数调用:

依然看代码

function f(xx) {
    this.x = xx;
}
f(5);

这个时候,函数 f里的this 绑定的是全局对象,如果是在浏览器运行的解释器中,一般来说是楼上说的 window对象。所以这里 this.x访问的其实是 window.x,当然,如果 window没有 x 属性,那么你这么一写,按照 js 的坑爹语法,就是给 window 对象添加了一个 x 属性,同时赋值。

3.构造器函数调用:

构造函数一直是我认为是 js 里最坑爹的部分,因为它和 js 最初设计的基于原型的面向对象实现方式格格不入,就好像是特意为了迎合大家已经被其他基于类的面相对象实现给惯坏了的习惯。
如果你在一个函数前面带上 new关键字来调用,那么 js 会创建一个prototype属性是此函数的一个新对象,同时在调用这个函数的时候,把this绑定到这个新对象上。当然new 关键字也会改变return语句的行为。看代码

function a(xx) {
    this.m = xx;
}
var b = new a(5);

上面这个函数和正常调用的函数写法上没什么区别,只不过在调用的时候函数名前面加了关键字new 罢了,这么一来,this 绑定的就不再是前面讲到的全局对象了,而是这里说的创建的新对象,所以说这种方式其实很危险,因为光看函数,你不会知道这个函数到底是准备拿来当构造函数用的,还是一般函数用的,所以我们可以看到,在jslint里,它会要求你写的所有构造函数,也就是一旦它发现你用了 new关键字,那么后面那个函数的首字母必须大写,这样通过函数首字母大写的方式来区分,我个人只有一个看法:坑爹:)

4.apply/call 调用:

我们知道,在 js 里,函数其实也是一个对象,那么函数自然也可以拥有它自己的方法,有点绕,就好像函数可以自己有属性也是一个函数。其中每个函数都拥有apply()这个方法,让我们构造一个参数数组传递给函数,同时可以自己来设置this 的值,这就是它最强大的地方,上面的3种函数调用方法,你可以看到,this 都是自动绑定的,没办法由你来设,当你想设的时候,就可以用 apply()了。apply接收2个参数,第一个是将传递给这个函数的 this的值,第二个是参数数组。看代码:

function a(xx) {
    this.b = xx;
}
var o = {};
a.apply(o, [5]);
alert(a.b);    // undefined
alert(o.b);    // 5

是不是很神奇,函数 a居然可以给o 加属性值。当然,如果你 apply的第一个参数传递 null,那么在函数a 里面 this 指针依然会绑定全局对象。你可能要问了,apply 函数是哪来的,因为在 js 里所有的函数都有一个共同的prototype,也就是传说中的 Function.prototype, 这个原型里有两个神奇的方法,一个就是这里的apply ,另一个就是让题主疑惑的 call
call()方法和 apply() 方法很类似,它们的存在都是为了改变this 的绑定,那call()apply() 有什么区别呢?就我个人看来,没啥鸟区别。。。开玩笑!刚刚说了,上面 apply()接收两个参数,第一个是你想要 this 绑定的对象,第二个是一个参数数组,注意是一个数组,你想传递给这个函数的所有内容都放在数组里,然后 apply() 函数会在传递形参时自动帮你展开,同时加入我上面提到的另一个神奇形参arguments。而 call() 呢,它的第一个参数也是你想要this 绑定的对象,但是后面可以接受不定参数,而不再是一个数组,也就是你可以像平时给函数传参那样把这些参数一个一个传递,当然,神奇形参 arguments还是不会少的。所以如果一定要说有什么区别的话,看起来是这样的

function a(xx, yy) {
    alert(xx, yy);
    alert(this);
    alert(arguments);
}
a.apply(null, [5, 55]);
a.call(null, 5, 55);

仅此而已。

相关文章

  • JS函数的定义与调用方法

    JS函数调用的四种方法:方法调用模式,函数调用模式,构造器调用模式,apply,call调用模式 1.方法调用模式...

  • JS this指向

    一、js中的四种调用模式s 构造函数调用:new Foo(); 对象方法调用:o.method(); 函数直接调用...

  • JS函数调用

    js 里函数调用有4种模式:方法调用、正常函数调用、构造器函数调用、apply/call 调用。无论哪种函数调用除...

  • js里函数调用的四种模式

    js 里函数调用有4种模式:方法调用、正常函数调用、构造器函数调用、apply/call调用。同时,无论哪种函数调...

  • 6.递归、call、apply的用法

    函数的四种调用模式 函数中的this,调用方式不同,指向不同 this与调用有关,与定义无关 函数调用模式 函数名...

  • this指向问题

    正在看《JavaScript语言精粹》这本书,正好看到有关函数中this的调用模式,其中有四种:方法调用模式、函数...

  • js的this指向总结

    this对象 js严格模式下没有window 一、普通函数 非严格模式 普通函数全局调用和局部调用都是指向wind...

  • this

    this this在面向对象编程过程中非常重要,它的值取决于调用模式。 在js中一共有四种调用模式:方法调用模式、...

  • js函数四种调用模式与this

    一、方法调用模式 如果一个函数作为一个对象的方法属性调用,那么他的调用模式就是方法调用模式。方法调用模式的this...

  • 这次再忘什么是this,我就直播吃电脑

    我们都知道,调用一个函数一共有四种调用模式: 方法调用模式定义:当一个函数被保存为对象的一个属性的时候,这个函数被...

网友评论

      本文标题:js里函数调用的四种模式

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