深入理解JavaScript系列(一): 函数的四种调用模式

最近一两个月开始转向前端,跟着组里的大牛们做着数据分析和展示的项目。前端并不像我去年大三的时候想的那么简单和浅薄,现在流行的富客户端+REST模式让前端开发大有可为。陆陆续续看了好几本关于js的书,对于js有了更深的认识和理解,也解决了自己之前的一些困惑。所以想写一个系列,来讲一讲JS中一些令人困惑的知识点,希望能给学习了JS基础,但是对JS理解不深的同学一点帮助。


这篇就先讲讲JS中函数的调用模式,或者说,JS中this的指向问题。

1.方法调用模式

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

function A() {
       this.x = 1;    //定义a.x
       this.b = function () {    //定义a.b
            this.helper = function () {     //定义a.helper
       	          console.log(this);  //4.console.log(a)
            }
            this.helper();  //3.调用a.helper(); 此时的helper,是一个方法,所以helper中的this指向a
       }
       this.b();    //2.调用a.b(),此时的b是a的一个属性,所以是一个方法,所以b中的this指向a
}
var a = new A(); //1.创建a对象

输出: A {x:1}

2.函数调用模式

当一个函数不是一个对象的属性时,就是被当做一个函数来调用的。此时this被绑定到全局对象。

function A() {
	this.x = 1;    
        this.b = function () {
              var helper = function () {
       		      console.log(this);
               }
              helper();  //此时的helper不是任何对象的属性,只是一个函数
        }
        this.b();
}
var a = new A(); 


输出:  Window {external: Object, ......}

3.构造器调用模式

用new关键字,此时this被绑定到创建出来的新对象上。

function A() {
    this.x = 1;    
    this.b = function () {
  	this.helper = function () {   //定义aa.helper
       	    console.log(this); //4.console.log(aa)
        }
      this.helper(); //3.调用aa.helper(); 此时的helper,是一个方法,所以helper中的this指向aa
    }
    var aa = new this.b();   //2.创建一个新的对象aa,所以b()中的this指向aa
}
var a = new A(); //1.创建a对象

输出:  A.b {} ;


另外,这里举Splunk吉祥物pony的例子来说一说new操作符做的事情:

function Pony(color) {
    // var this = Object.create(Pony.prototype);
 
    // instance members
    this.color = color;
 
    // private members
    var age = 50;
 
    // private methods
    function secreteMethod() {
        console.log('Secret!');
    }
 
    // make private member visible due to closure
    this.getAge = function() {
        console.log('My age is : ' + age);
    };
 
    // return this;
}
 
// methods
Pony.prototype.tellColor = function() {
    console.log('I am ' + this.color);
};
 
// static attributes
Pony.type = 'horse';
 
var pony = new Pony('white');
pony.tellColor();
pony.getAge();


what happens?
var pony = new Pony('white');
// equals
var pony = {};
pony.__proto__ = Pony.prototype;
Pony.call(pony, 'white');

4.apply调用模式

js是一门函数式的面向对象编程语言,所以函数可以有方法。apply(or call)方法允许我们构建一个参数数组传递给调用函数,也允许我们选择this的值。它接受两个参数,第一个是要绑定给this的值,第二个是一个参数数组。
function People (name) {
		this.name = name;
} 
People.prototype.greet = function () {
		console.log('hi,'+this.name);
};
var dog = {
	name: 'hobbo'
};
People.prototype.greet.apply(dog);
输出: hi,hobbo


总结:
  • this默认指向global object
  • 当函数作为对象的属性被调用时,函数中的this指向那个对象   
  • 当使用new操作符来调用函数时,函数中的this指向新创建的对象
  • 当使用apply或者call来调用函数时,this指向被传给call活apply的第一个参数。如果第一个参数是空或者不是一个对象,this指向global object


  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值