美文网首页
四种调用模式

四种调用模式

作者: 郑馋师 | 来源:发表于2019-12-12 20:53 被阅读0次

调用模式:

函数调用模式。

就是通过函数来调用,规范写法为:function fn(){} fn(); 函数中this的指向->window。案例如下:

var name = `window`;
    var obj = {
        name: `obj`,
        getName: function() {
            function c () {
                console.log(this.name); // 因为是函数调用模式,所以this指向window全局变量,所以输出为window
            }
            // 只看这个函数是怎么调用,不管函数是在哪声明的!
            c ();
        }
    };

    obj.getName();

方法调用模式。

就是通过对象的属性来调用,eg

    let obj = {
        say: function() {
            console.log(this);
        }
    };
    obj.say();
//函数中this的指向->当前对象。eg:
  var age = 10;
    var obj = {
        age: 11,
        getAge: function() {
            console.log(this.age);// 11
        }
    };
obj.getAge();//因为是方法调用模式,this指向当前的对象obj。

构造函数模式

如果是作为构造函数来调用,那么this就是指向:new创建的新对象,这个是mdn的eg:

 function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}
const car1 = new Car('Eagle', 'Talon TSi', 1993);
console.log(car1.make);
// expected output: "Eagle"

这里顺便一提new,他就是

  • 创建一个空的简单JavaScript对象(即{});
  • 链接该对象(即设置该对象的构造函数)到另一个对象 ;
  • 将步骤1新创建的对象作为this的上下文 ;
  • 如果该函数没有返回对象,则返回this。

函数上下文(借用方法模式)。

上下文模式中this的指向和前三种模式不一样,它的this指向可以改变,而前三种模式是固定。函数上下文在我理解就是函数作用域。基本语法:apply和call 后面都是跟两个参数
apply和call第一个参数一样:表示使用那个对象来调用函数;apply第二个参数是:是一个数组或伪数组,数组的值做为函数的参数被传入;call第二个参数是:是基本数据类型(number string boolean);eg:
若要求一个数组中的最大值
常规写法

    let arr = [9, 1, 4, 101, 7, 22, 8];
    let maxNum = arr[0],
    for(i=1; i <arr.length; i++) {
        if(arr[i] > maxNum) {
            maxNum = arr[i];
        }
    }
    console.log(maxNum);

使用上下文调用模式(apply)

    let arr = [9, 1, 4, 101, 7, 22, 8];
   let maxNum=Math.max.apply(window,arr);//Math.max是window中的排序方法我们可以通过apply借用window中Math.max方法来对数组进行排序。
    console.log(maxNum);

当一个函数被保存为对象的一个方法时,如果调用表达式包含一个提取属性的动作,那么它就是被当做一个方法来调用,此时的this被绑定到这个对象。也就是call的方法

  let a = 1
   let obj1 = {
      a:2,
      fn:function(){
        console.log(this.a)
      }
    }
    obj1.fn.call(obj1)//2    

此时的this是指obj1这个对象,obj1.fn.call(obj1),由于没有参数,所以只要写出this是谁就可了。事实上谁调用这个函数,this就是谁。补充一下,DOM对象绑定事件也属于方法调用模式,因此它绑定的this就是事件源DOM对象。eg:

document.addEventListener('click', function(e){
    console.log(this);
    setTimeout(function(){
        console.log(this);
    }, 200);
}, false);

点击页面,依次输出:document和window对象
是因为点击页面监听click事件属于方法调用,this指向事件源DOM对象,即obj.fn.apply(obj),setTimeout内的函数属于回调函数,可以这么理解,f1.call(null,f2),所以this指向window。

函数调用模式:

普通调用

普通函数的调用,此时的this被绑定到window

最普通的调用
function fn1(){
      console.log(this)//window
    }
fn1()
函数嵌套
function fn1(){
    function fn2(){
        console.log(this)//window
    }
    fn2()
}
fn1()

这时候也是window

把函数赋值之后再调用
var a = 1
var obj1 = {
    a:2,
    fn:function(){
        console.log(this.a)
    }
}
var fn1 = obj1.fn
fn1()//1

obj1.fn是一个函数function(){console.log(this.a)},此时fn1就是不带任何修饰的函数调用,function(){console.log(this.a)}.call(undefined),按理说打印出来的 this 应该就是 undefined 了吧,但是浏览器里有一条规则:
如果你传的 context 就 null 或者 undefined,那么 window 对象就是默认的 context(严格模式下默认 context 是 undefined)
因此上面的this绑定的就是window,它也被称为隐性绑定。

如果你希望打印出2,可以修改fn1()为fn1.call(obj1),显示地绑定this为obj1

回调函数

被作为实参传入另一函数,并在该外部函数内被调用,用以来完成某些任务的函数,称为回调函数。回调函数就是写给别人用的函数,是写个浏览器回头调用的,调用的时机是等到浏览器的ready state=4,也就是读取服务器相应完了才会用的。要注意写给别人的才是回调,写给自己的不是回调
eg:

let f1=()=>{}
let f2=(fn)=>{fn()}
f2(f1)

此时fq的地址就作为fw中的一个参数被调用,所以fq就是一个回调函数。
直接调用的f2则不是回调函数。若是这样

let f1=()=>{}
let f2=(fn)=>{}
f2(f1)

虽然此时f2里面没有写怎么调用f1,但f2接受了f1这个参数肯定是要用的,所以此时f1仍然是回调,此时f2对于f1的调用方法就是不管他,让他自生自灭,这也算是调用了。

再看会开始的那个eg

let a = 1
function f1(){
    (function (){var a = 2})()
    console.log(a)//1
}
f1()

其实它仍旧是最普通的函数调用,f1.call(undefined),this指向window,打印出的是全局的a。
借此,我们终于可以解释为什么setTimeout总是丢失this了,因为它也就是一个回调函数而已。回调函数就是会自动指向window而非当前对象,这也被称为回调函数的this丢失。

构造器调用模式:

new一个函数时,背地里会将创建一个连接到prototype成员的新对象,同时this会被绑定到那个新对象上

function Person(name,age){
// 这里的this都指向实例
    this.name = name
    this.age = age
    this.sayAge = function(){
        console.log(this.age)
    }
}
var dot = new Person('Dot',2)
dot.sayAge()//2

相关文章

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

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

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

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

  • this

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

  • JS this指向

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

  • this指向问题

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

  • 四种调用模式

    调用模式: 函数调用模式。 就是通过函数来调用,规范写法为:function fn(){} fn(); 函数中th...

  • this is awful

    函数的四种调用模式 方法调用模式 上面的代码中,baz是foo对象的一个属性(方法),这时候baz作用域中的thi...

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

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

  • 函数四种调用模式

    很是生硬地了解一波函数调用,各种给的解释都是大同小异,也许,我理解的函数调用是对this的初始化,不同的调用方式,...

  • 四种js调用模式

    自开始做一些前端开始,一直浑浑噩噩用js,有些东西似懂非懂,抽点时间看书学习下。 调用一个函数将暂停当前函数的执行...

网友评论

      本文标题:四种调用模式

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