簡單談談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

 

好了,就總結到這裏。小黃毛,你懂了嗎?

相關文章
相關標籤/搜索