深入理解函数调用的4种模式

前面的话

函数作为任意一门编程语言都是核心。想精通js,在这方面多下功夫是必须的。JavaScript中函数既对象,这篇文章是小柒看过很多博客之后总结出来的。

函数调用的4种模式

● 作为普通函数调用
● 作为对象的方法调用
● 构造函数调用
● call与apply方法的间接调用

作为普通函数调用

 function add(x, y) {
         return x + y;
     }
     var sum = add(1, 2);// 这就是普通的函数调用
    console.log(sum);

使用普通函数的调用时,在非严格模式下,this被绑定到全局对象
在严格模式下,this是undefined。

 function add(x, y) {
         console.log(this);//window
     }
     add();
     function add(x, y) {
         'use strict';
         console.log(this);// undefined
     }

重写

普通函数的调用this会绑定到全局对象window,所以全局变量可以被重写

    var a = 0;
     function fn() {
         this.a = 2;
     }
     fn();
    console.log(this, this.a, a);// window 2 2

作为对象的方法调用

当一个函数作为一个对象的属性时,可以称为这个函数是对象的方法。当方法被调用时this被绑定到该对象上。

  var obj = {
        fn: function() {
            console.log(this);//  {fn:f}
        }; 
  obj.fn();// 这就是作为一个对象的方法调用,此时this指向的就是obj这个对象

作为对象的方法调用,此时通过this可获取或改变对象的属性值

   var obj = {
       a : 1,
       m: function() {
           return this;
       },
       n: function() {
           this.a = 2;
       }
    }
    console.log(obj.m().a);// 1
    obj.n();
    console.log(obj.m().a);// 2

注意:与变量不同是this没有作用域的限制,嵌套函数不会从调用它的函数中继承this.
如果嵌套函数作为对象的方法调用,那么其this指向调用该方法的对象;
如果嵌套函数作为普通函数调用,那么在非严格模式下,指向window,在严格模式是undefined

 var obj = {
     m: function() {
         function n () {
             return this;
         }
         return n();// 作为普通函数调用
     }
 }
 console.log(obj.m());// window

如果想访问外层的this可以将其保存起来

 var obj = {
     m: function() {
         var that = this;
         function n() {
             return that;
         }
         return n();
     }
 }
 console.log(obj.m() === obj);// true

构造函数模式

如果函数或者方法调用之前有new关键字,它就是构造函数的调用

 function fn() {
     this.a = 1;
 }
 var obj = new fn();
 console.log(obj.a);//1
/*

构造函数通常没return关键字,这种情况下构造函数调用会返回一个新的对象,构造函数的this 将指向这个对象

 function fn() {
     this.a = 2;
 }
 var test = new fn();
 console.log(test);// {a:2}

当构造函数有return关键字,但无返回值时,this仍指向new fn()返回的新对象

 function fn() {
     this.a = 2;
     return ;
 }
 var test = new fn();
 console.log(test);// {a: 2}

当构造函数有return关键字,且返回一个对象。那么此时不会产生新的对象,test的值就是返回的obj对象

 function fn() {
      this.a = 2;
	  return obj;
 }
 var test = new fn();
 console.log(test);// {a: 1}

call与apply方法的间接调用

函数本生也是对象,每个函数都有call()与apply()方法。使用它们将可以间接调用函数 ,call()与apply()可以改变this指向。两个方法的作用是相同的,只是参数列表不同。
详解call()与apply()可以查看小柒的另一篇文章“深入理解call()与apply()”

var obj = {};
function sum(x, y){
    return x + y;
}
console.log(sum.call(obj,1,2));// 3
console.log(sum.apply(obj,[1,3]));// 4

参考:
阮一峰老师的文章:http://javascript.ruanyifeng.com/grammar/function.html
其他优秀的文章:
http://www.cnblogs.com/xiaohuochai/p/5702813.html#anchor1

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值