目录
https://mp.csdn.net/postedit/90049141
this指向集合
1. window:
1.直接在全局输出this
2.函数打印this,并且直接调用
3.定时器中普通函数this为window
4. 匿名函数自执行事件中的this
以下代码分别对应this指向window的四种基本演示:
1. console.log(this); //window 2. function fn(){ console.log(this); //window } fn() 3. setTimeout(() => { console.log(this); //window }, 1000) 4. (function () { console.log(this);//window })();
2. 事件this
哪个对象触发,this就是那个对象;
如下,btn触发事件,那么this就指向btn;
btn.onclick =function(){ alert(1); }
3. 实例:this
new 构造函数 - - > this就是实例
function fn(){ console.log(this) // 实例 -- >fn{} } new fn();
4. 箭头函数
this走定义箭头函数的域,也就是它在哪里定义的,看定义域的this是谁就是谁;
注意:的是箭头函数不能new,一new就报错, 箭头函数也没有arguments;
document.onclick = function(){ setTimeout(()=>{ console.log(this); // document },1000) } // 在function的域中定义,document触发,所以指向是this; 请注意并非在setTimeout中定义;
5. 对象的this
看它是否有主,有主是主,没主就是window;
简单来说,直接看点前边是否有内容,有this就是点前边的
var obj = { name : "chan", say : function(){ console.log(this.name); // chan } } obj.say(); // 这时候.前边是obj那么this就指向obj; 如果是say(),那就是全局,也就是window;
修改this的方法
一个函数,天生自带一些属性和方法;
其中这3个可以改变this指向。
序列 | 方法 | 写法 | 参数 | 注意 |
---|---|---|---|---|
1 | call() | call ( this , 实参) | 参数无数个 | this如果写的是 null、undefined 指向为window |
2 | apply() | apply ( this , 实参) | 数组 [1,2,3] | |
3 | bind() | bind ( this , 实参) | 参数无数个 |
apply、call和bind的区别
在JS中,这三者都是用来改变函数的this对象的指向的,他们有什么样的区别呢;
我们来看个例子:
var men = {
name : "蓝蓝",
sex : "男",
age : 21
};
var women = {
name : "chan",
sex : "女",
age : 17,
say : function(job,page) {
alert(this.name + " , " + this.sex + " ,今年" + this.age + this.job +this.page);
}
};
women.say();
毋庸置疑,输出肯定是 chan,女,17,
那么我们可以通过上述的方法来改变this指向,来看看它的使用方法,再判断它的相同与不同之处,
//对于call
women.say.call(men,“警察”,“二狗”);
//对于apply
women.say.apply(men,[“老师”,“赵四”]);
//而对于bind,
women.say.bind(men,“服务员”,“海燕”)();
//另一种写法
function fn(a,b){
console.log(this,a,b);
}
let f = fn.bind(document,1,2); // 指向document,输出1,2
f();
通过以上例子不难发现,他们的相同点与不同点;
相同点:
- 1、都是用来改变函数的this对象的指向的;
- 2、第一个参数都是this要指向的对象;
- 3、都可以利用后续参数传参;
不同点:
- 1、call和apply都是对函数的直接调用,而bind方法返回的仍然是一个函数,后面还需要()来进行调用才可以输出代码。
- 2、call、bind的实参都是与say方法中是一一对应的,而apply的第二个参数是一个数组,数组中的元素是和say方法中一一对应的,这就是两者最大的区别;
小练习
1、改变this的小例子
1、选出数组中最大的数字
let ary = [8,6,4,75,24,48,44,43]
Math.max.apply(null,ary)
// 简单理解为把取数字最大的方法给ary
2、this指向的小练习
let obj = {
fn: function () {
console.log(this)
}
}
obj.fn() // 对象,看有没有主,有主this就是 . 前面的,没有就是window;
let f = obj.fn; //相当于把obj.fn的地址赋值给f
f(); //所以当调用f的时候,this就指向f;
document.onclick =function(){
console.log(this);
}
//
document.onclick = fn; // 把函数地址赋值给点击事件;
function fn(){
console.log(this);
}
document.onclick = fn();
function fn(){
console.log(this);
}
document.onclick = function(){
fn();
};
function fn(){
console.log(this);
}
document.onclick = fn();
function fn(){
console.log(this) //window
return function(){
console.log(this); //document
}
}
document.onclick = fn()();
function fn(){
console.log(this) // window
return function(){
console.log(this); // window
}
}
document.onclick = new fn();
function fn(){
console.log(this) // 实例 -- >fn{}
return function(){
console.log(this); // document
}
}
document.onclick = new new fn;
function fn(){
console.log(this) // 实例 -- >fn{}
return function(){
console.log(this); // 实例 {}
}
}
document.onclick = new new new fn();
function fn(){
console.log(this); // fn{}
return function(){
console.log(this); // {}
} // 报错
};
document.onclick = function(){
new fn;
}
function fn(){
console.log(this);
}
document.onclick = function(){
setTimeout(()=>{
console.log(this); // document
new fn;
},1000)
}
function fn(){
console.log(this);
}