今天跟大家一起简单的来了解一下js中一个有趣的东西,this.
在js中我们用面向对象的思想去编写的时候,各个模块之间的变量就不那么容易获取的到了,当然也可以通过闭包的方式拿到其他函数的变量,如果说每获取一个变量,都要用闭包的方式去获取,就显得太繁琐了,这时候js中也提供了一种方法来获取其他的变量,当然前提是这些函数之间是有联系的,比如函数2是绑在函数1的原型上的,那么函数1中用this指明的一个变量,在函数2中同样可以用this来获取到,当然着其中是有着一定的规则的。那么接下来我给大家对this做一个详细的介绍
一:到底什么是this呢?
概念:执行上下文,this一般存在于函数中,表示当前函数的执行上下文, 如果函数没有执行,那么this没有内容,只有函数在执行后this才有绑定。
注意:this的指向只能是对象,当然别忘记了数组也是一个特殊的对象。
二:this到底指向的是谁呢?
this的指向其实是跟this的执行位置是有关的,不同的位置执行位置,this的指向就可能发生改变。
Tip:this被谁执行了,this就是执行谁的,这时候一定要看清楚this是被谁直接执行的!
那么接下来给大家总结几种this指向的问题。
1:默认执行:this指向了window,在严格模式下,this指向了undefined
eg:
function fn(){
"use strict";
console.log(this);
}
fn();
这个时候在严格模式下,指向的是undefined,去掉严格模式,指向window
2:隐式执行(通过对象执行):通过上下文对象执行
这里给大家整理五种常见的this错误指向的例子
2.1改变函数引用
eg:
var obj = {
name:'admin',
show:function(){
console.log(this.name);
}
}
var newShow = obj.show;
newShow();
//this指向了window,函数的执行对象变成了window
2.2函数传参
eg: var name='window'; var obj = { name: 'obj', show: function(){ console.log(this.name); } } function trigger(fn){ fn(); } trigger(obj.show); //this指向window
2.3:定时器传参
var name='window';
var obj = {
name: 'obj',
show: function(){
console.log(this.name);
}
}
setTimeout(obj.show,1000);
//this指向了window
2.4:DOM对象事件
var name = 'window';
var oHtml = document.documentElement;
var obj = {
name: 'obj',
show: function(){
console.log(this.name);
}
}
oHtml.name = 'DOM';
oHtml.onclick = obj.show;
//this指向了window
2.5:arguments类数组改变this指向问题
tip:传入过多的实参,多余的实参虽然没有什么用,但也是保存在函数中了
var length = 10;
function fn(){
console.log(this.length);
}
var obj = {
length: 5,
method: function(fn){
fn();
arguments[0]();
}
};
obj.method(fn,"111","222");
//打印结果为10,3
tip1:
obj.method的value并不是一个可以直接直接执行的函数,通过obj.method并不能执行函数,
所以this指向的并不是obj,输出的不是5,this指向的是function这个无名函数,他的执行对象直接是window,发生隐式丢失
但是arguments[0]();也会执行,因为传入的第一个参数就是一个函数,同时传进了两个多余的实参,所以打印出的为3
tip2:
数组是很特殊的对象,他的索引值相当于是obj2对象中的属性值。所以说数组,类数组也会改变this指向问题。
3:显示执行
通过函数的bind或call或apply执行
tip:当发生隐式执行的时候,还希望能拿到指定的this,可以通过函数的一些方法,强行改变到指定的this
这里拿bind方法给大家做一下介绍
bind()方法会创建一个新函数,称为绑定函数,当调用这个绑定函数时,绑定函数会以创建它时传入bind()方法的第一个参数作为this,
传入 bind() 方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。
tip:改变this的指向,简单来说,可以让没有这个功能的对象,具有另一个对象的功能
当blind();有多个参数的时候,第一个参数表示this的指向,其他的参数会与原函数的参数一起放在新函数中
eg1:
var a = {
name:"admin"
}
var b = {
name:"uesr",
show:function(){
console.log(this.name);
}
}
b.show();
var c = b.show.bind(a);
c();
//此时的c能够获取到a里面的name,利用a强行将this指向了a
eg2:
常用方式,用来改变函数内计时器函数this的指向
for(var i=0;i<ali.length;i++){
ali[i].onclick = function(){
setTimeout(function(){
console.log(this)
}.bind(this),500)
}
}
//不用blind()方法,this直接指向的是window,强行给计时器函数加了blind()方法,这时候谁触发了函数的执行,this就指向了谁。