简单谈谈JavaScript中的this

  是夜,想着考量下小黄毛近期的JavaScript进阶如何了,鉴于近期一直在接触Vue 2.0,索性就围绕this编写了个代码片断,javascript

给其一个测量,毕竟写js的程序员都知道,JavaScript的函数调用时会隐性的接收到两个附加的参数:this和arguments。java

 

一、先上代码:

 

/**
 * this 
 */

var ajaxThis = (function() {
	
	global.a = 2;
	
	function fn(b) {
		this.b = b;
		
		console.log(this.a);
	}
	
	var obj = {
		a : 4,
		fn : fn
	};
	
	
	fn();// 题1
	obj.fn(); // 题2
	fn.call(obj); // 题3
	fn.call(null);// 题4
	fn.apply(obj);// 题5
	fn.apply(null);// 题6
	
	var fnInstance = new fn(8);
	console.log(fnInstance.b);// 题7
})();

 

 注:这些题倒不难,只要你把握好JavaScript中的this到底指向谁,那么就问题不大。程序员

 

二、小测验答案

题1:2ajax

题2:4编程

题3:4数组

题4:2app

题5:4函数

题6:2this

题7:undefinedspa

    8

 

不要好奇,第7题的确是输出两个值

先说些闲话,当你对JavaScript接触使用的多了,就能感觉到它的方面之处,同时也可以避开它的缺点,发扬其优势。

 

在解析答案以前,先来说解一下到底如何判断this的取值吧。

其实,this的值取决于调用的模式。

调用模式?那都有哪些调用模式呢?

总的来讲,JavaScript的函数调用总共有4种模式,是的,你没听错,就是4种!!!

 

哪4种?

  • 方法调用模式

  • 普通函数调用模式

  • 构造器调用模式

  • apply/call调用模式

 

而针对这四种调用模式,参数this的取值会有所差别:

• 方法调用模式

  何为方法调用?固然泛指针对对象来讲的了。该种调用模式说明,函数在某个明确的上下文对象中调用时,this绑定的是这个上下文对象。

  e g.   题2的  obj.fn(); // 调用的对象是obj,因此this绑定的就是obj,因此fn()内部console.log(this.a)输出的即是obj.a,即为4

 

• 普通函数调用模式

  普通函数调用?指的即是直接调用函数。这种调用模式,默认状况下,若是函数是被直接调用的,则this绑定到全局对象; 

若是在严格模式下(即 'use strict'),就绑定到undefined。

  e g. 题1中的  fn(); // 由于没有指明调用方,同时又是非严格模式,因此,fn()函数内部的this绑定到全局对象,因此this.a的值为global.a,即为2

 

• 构造器调用模式

  构造器调用模式?这个应该都不陌生吧?!固然指的是经过new操做符来调用的函数啦!在这里有点相似于面向对象编程的概念,构造器函数内部的this固然

绑定到这个新建立的对象了。这种调用模式,指的即是:若是函数经过new操做符调用,this绑定的是新建立的对象。

  e g. 题7中的    var fnInstance = new fn(8); // 由于是经过new操做符调用的fn函数,因此this指向当前新建立的对象,然而这个对象没有a这个属性,因此输出undefined

            console.log(fnInstance.b);  // 然而由于给fn函数传入了值8,因此……

 

• apply/call调用模式

  apply/call又是什么鬼?我先来解说它们的用法吧!

  a) apply()和call()方法的第一个参数都是要调用函数的对象。用apply()和call()调用函数时,函数内的this属性老是引用这个参数;

  b) call()函数剩余参数是传递给要调用的函数的值,它们的数量能够是任意的;

  c) apply()方法和call()方法相似,只不过它只接收两个参数,除了调用者以外,它的第二个参数是一个带下标的集合(好比数组,但也能够不是数据),

apply()方法把这个集合中的元素做为参数传递给调用的函数。

 

  OK,如今从新回到主题:该种调用模式,this又指的是谁?细心的你可能已经注意到,上面介绍他们的用法是,已经提到函数内的this属性老是引用第一个参数,

也就是调用函数的对象。也就是说,函数经过apply/call调用,this绑定的是指定的对象,然而,若是把null/undefined做为this的绑定对象传入apply/call,

在调用时会被忽略,实际应用的是默认绑定规则。

  

  e g.     fn.call(obj); // 题3,答案为console.log(obj.a),即为4

 

       fn.call(null);// 题4 ,由于null被忽略,答案为console.log(global.a),即为2

 

       fn.apply(obj);// 题5 ,答案为console.log(obj.a),即为4

 

       fn.apply(null);// 题6 ,由于null被忽略,答案为console.log(global.a),即为2

 

好了,就总结到这里。小黄毛,你懂了吗?

相关文章
相关标签/搜索