关于js函数中this的指向的问题

@(javascript)[JavaScript中this的指向]javascript

关于js函数中this的指向的问题

javasript函数中this的指向一直都是许多编程入门新手的一个问题,老师把这个this的指向弄错误。下面咱们能够来看看关于this指向的几种状况。html

不过在讲以前,请各位始终记住一句话: JavaScript中的this一直指向触发这个事件(函数)的这个Objoct(对象)。java

第一种:函数直接添加在行内

<button onclick="alert(this.innerHTML);">this就是指向这个div盒子</button>
复制代码

点击看看: 此时的这个alert(this.innerHTML);事件是直接写在button这个元素行内的。是这个button元素触发的这个事件。编程

第二种:经过对象.事件名来实现

这是html代码函数

<button id="box">经过js事件的点击事件</button>
复制代码

下面是js代码ui

document.getElementById("box").onclcik = function(){
	alert(this.innerHTML);
}
复制代码

this

以上的两种方式都很好理解,也不作过多的说明。spa

第三种:函数的调用的形式

这种方式也是存在许多的变种,先来看看上面例子的一个变种。 这是html代码code

<button id="box1">经过js事件的点击事件</button>
复制代码

下面是js代码htm

document.getElementById("box1").onclick = a;
function a(){
	alert(this);
}
复制代码

这一种形式的事件与上面的实际上是同样的,不过是单独定义了一个函数,而后点击调用这个函数。

在看看下面的例子

<button id="box1">经过js事件的点击事件</button>
复制代码

下面是js代码

document.getElementById("box1").onclick = function(){
	a();
}
function a(){
	alert(this);
}
复制代码

此时的这个与上面的有很类似,不一样的就是此时的这个a函数是在一个事件函数里面执行的。此时的逻辑是:我点击这个ID为box1的button,让后触发事件后面的函数function(){a();}。此时呢里面的a函数其实尚未执行。到这个函数执行的时候,执行到里面的函数了,a函数本身调用执行(函数加括号执行),那么问题来了,是谁调用的这个a函数呢?答案是:window。由于不存在上面说的两种以及Object.函数的形式。这个就有点像是定义了一个函数自执行。

像这样

function t(){
	console.log(this);
}
/** * 此时的这个 t 函数是由谁调用的呢(也就是鼠标哪个对象让他执行的?) * 答案是的 null * 而在 js 中,若是 this 的指向是null会自动转换为 window */
t();
复制代码

或者是这样:

function t(){
	function t2(){
		console.log(this);
	}
	t2()
}
t();
复制代码

OK!接下来看看这个:

function intro(){
	console.log('名字是'+ this.name,this );
}
var dog = {name: "狗"};
dog.intro = intro;
dog.intro(); // 狗
复制代码

分析一下:此时先定义了一个名字是intro的一个函数,在定义一个dog对象并赋值name=狗。下面的代码就是在dog这个对象上添加一个intro对象,赋值为一开始定义的那个函数intro。此时的这个dog对象就多了一个属性intro,值是函数。接着在调用这个dog.intro();。那么是谁调用的呢?很明显是这个dog对象调用的这个函数。因此此时的这个this就是指向dog对象。那this.name就是了。

OK!再来:

function intro(){
	console.log('名字是'+ this.name,this );
}
var dog = {name: "狗"};
dog.intro = intro;
dog.intro(); // 狗

var cat = {name:"猫"};
cat.intro = dog.intro;
cat.intro(); // 猫
复制代码

如今多了一个cat,看这句cat.intro = dog.intro;。这个是把dog下面的intro方法赋值给了cat下面新建的一个intro方法。此时涉及到一个内存的问题。js中的对象,函数等都是存放在内存中,给其余对象赋值为这个函数的时候就是让这个对象的这个属性指向内存中的这个函数,因此,无论上面的是怎样赋值,catdogintro的值是指向同一个函数的。不一样的是调用他们的对象不一样,致使this不一样,因此最后的this.name的值不一样。

再来看看这个呢?

function intro(){
	console.log('名字是'+ this.name,this );
}
var dog = {name: "狗"};
dog.intro = intro;
dog.intro(); // 狗

var cat = {name:"猫"};
cat.intro = dog.intro;
cat.intro(); // 猫

(cat.intro = dog.intro)(); // 空 this 指向window```javascript
function intro(){
	console.log('名字是'+ this.name,this );
}
var dog = {name: "狗"};
dog.intro = intro;
dog.intro(); // 狗

var cat = {name:"猫"};
cat.intro = dog.intro;
cat.intro(); // 猫

(cat.intro = dog.intro)(); // 空 this 指向window
复制代码

此时的在上面的就是多了一句(cat.intro = dog.intro)();。那为何就指向window了呢? 上面的这个例子,涉及到的是关于计算机里面的计算,cat.intro = dog.intro 这是一个赋值运算,而赋值运算的结果是 = 右侧的值,此时这个值并不属于任何一个对象,而这个值是一个空,也能够说是一个 null ,因此此是为 null 转为指向 window。能够这么作一个比喻:

一天张三去面馆吃面,给老板说:“老板,一碗牛肉面”,作好面后,此时的这碗牛肉面这个就有了。至关于上面的intro函数,此时呢他并不属于张三。当老板把这碗面端到张三面前,这是才属于张三。OK。李四也去吃面,进入面馆,看见张三的面。对老板说:“老板,来一碗和他同样的面”。此时老板须要计算,这碗面是什么面?至关于上面的cat.intro = dog.intro计算。老板计算后才知道这碗面是牛肉面。此时让一个加括号执行,那确定就不行了。此时的这碗面并不属于李四。赋值的结果是是什么呢?当老板把这碗面端到李四面前,这是才属于李四。这就是结果。

须要注意的点就是cat.intro = dog.intro只是一个赋值过程,值是=右边的东西。执行cat.intro = dog.intro会致使一个结果就是cat下面多了一个intro属性而且有值。

基本普通的函数中的this存在的问题就是这么多,其余的也就是上面的一些变种。

不过,能够发现,由于this指向window的存在,会致使污染全局,因此多数时候使用构造函数new的方式更可取,这样this才不会指向全局避免污染全局。

上面说了这么多。其实也就是最开始说的那句: JavaScript中的this一直指向触发这个事件(函数)的这个Objoct(对象)。

相关文章
相关标签/搜索