This指向
1.事件绑定中的this
1.1 行内绑定
<button id="btn" onclick="clickFun()">点击</button>
<button id="btn" onclick="console.log(this)">点击1</button>
// 运行环境在节点中,this指向此节点对象
<script>
// 事件绑定
function clickFun(){
console.log(this);// 在普通函数中,this指向window
}
</script>
直接绑定在行内事件上,
this指向绑定的节点对象
创建一个函数,再绑定在行内元素上,
this指向window。因为this是在普通函数中,只是被用在行内元素上。
1.2 事件绑定和动态绑定
<button id="btn" onclick="clickFun()">点击</button>
<script>
btn.onclick=function(){
console.log(this);// 指向调用的对象 button
}
// addEventListener事件监听和事件绑定一样,this都指向此节点对象
2.函数内部的this指向
2.1 普通函数 指向window
function test(){
console.log(this);// 指向window
}
test()
2.2 对象调用 this指向,谁调用就指向谁
var obj={
a:1,
say:function(){
console.log(this);// 指向Object
}
}
obj.say();//say()被obj调用,所以say()里面的this指向obj
2.3 多层嵌套的对象
多层嵌套的对象,内部方法的
this指向 离 被调用函数 最近 的对象(window也是对象,其内部对象调用方法的this指向内部对象, 而非window)。
var o = {
a: 10,
b: {
fn: function () {
console.log(this);// 指向b对象
console.log(this.a);// undefined 在对象b中,找不到a
}
}
}
o.b.fn();// 找最近的对象
fn函数离b对象近,this指向b对象,this.a在b对象中没有值,返回了undefined
2.4 对象中函数的赋值
var obj={
a:3,
call:function(){
console.log(this); //指向window
console.log(this.a);// undefined
}
}
var f =obj.call;
f();
//可以写成这样
var f=function (){
console.log(this);
console.log(this.a);// 函数中找不到a
}
f();// 普通函数中,this指向window
为什么会指向window? ? ?
因为函数是对象,对象是按引用传递的
obj.call赋值给f , 相当于把obj.call 的函数赋值给了变量f
也就相当于把obj.call的引用指向了f , 在变量f处调用
f为window对象的属性 , 所以this指向了window
3. 构造函数的this指向
new关键字改变了函数内this的指向,使其指向刚创建出来的对象
function Fn() {
this.user = "追梦子"; // a.user="追梦子
}
var a = new Fn();//this指向新创建出来的实例对象a
console.log(a.user);//追梦子
在构造函数中,当函数中有了return,已经不能称为构造函数了
function fn() {
this.user = '追梦子';
return {}; //undefined
return function(){}; //undefined
return 1; // 追梦子
return undefined; // 追梦子
return null; // 追梦子
}
var a = new fn();
console.log(a.user);
/*
fn的this指向了a,a.user===‘追梦子’;返回值为对象,函数,数组时,改变了this的指向,使其指向return的值,在函数fn中,对象,函数,数组没有user这个属性,返回undefined。
返回值为基本数据类型时,this指向不改变,仍指向a实例。
*/
new触发函数时,当函数return
[] {} function时,this指向return的值(
return的不是引用数据类型时,不改变this的指向,仍指向实例对象)
原型对象中的this
原型对象中this指向new出的实例对象
4. call(),apply(),bind()() 改变this的指向
`this`指向传入的对象 没有传参,`this`指向`window`
4.1 func.call(obj,参数1,参数2....)
作用1:调用函数
var obj = {
name: "132"
}
function fn(){
console.log(this);
}
// 不写参数 只是单纯的调用函数,fn的this依旧指向window
fn.call();
作用2:改变this的指向
var obj = {
name: "132"
}
function fn(a, b) {
console.log(this);
console.log(a + b);
}
// 将函数fn中的this指向obj对象,类似与obj.fn(),函数也可以传参
fn.call(obj, 1, 2);
4.2 func.apply(obj,[参数1,参数2...])
作用1:调用函数
var obj = {
name: "222"
}
function fn(){
console.log(this);
}
// 不写参数 只是单纯的调用函数,fn的this依旧指向window
fn.apply();
作用2:改变this的指向
var obj = {
name: "132"
}
function fn(arr) {
console.log(this);
console.log(arr); // 传入的时候为字符,输出的时候是字符串
}
// 将函数fn中的this指向obj对象,类似与obj.fn(),函数也可以传参
fn.apply(obj, [red]);
4.3 func.bind(obj)(参数1,参数2...)
不会调用原来的函数,可以改变this的指向
改变this的指向
var obj = {
age: 12
};
function fn(a,b) {
console.log(this);
console.log(a + b);
}
// 不能立即调用函数,调用函数时,可以bind()() 调用 或者
fn.bind();
// this指向obj 返回的是原函数改变this指向之后的新函数
var f = fn.bind(obj,1,2);
f();
使用bind的场景: 不需要立即调用函数,但又想改变函数内部的this指向
按钮点击后,禁用按钮,2秒后开启按钮
var btn = document.querySelectorAll('button');
for (var i = 0; i < btn.length; i++) {
btn[i].onclick = function () {
this.disabled = true;// 这个this指向btn
setTimeout(function () {
// 定时器中的this指向btn 但不立即执行
this.disabled = false;
// 这里this是定时器外的,指向btn对象,这两种是一样的
}.bind(this), 2000)
// }.bind(btn), 2000)
}
}
5. 在定时器中
this指向window
var x=1;
var o={
x:2,
fn:function(){
console.log(this.x);
console.log(this);
}
}
o.fn();//2 Object
setTimeout(o.fn,1000);//1 window
// o.fn引用传递
3. 箭头函数
箭头函数中没有
this,也没有arguments,主要看写在哪里,找其上下文中的this
在全局中,this===window
在函数方法中,主要看函数this的指向,this===function中的this指向
4. 在全局中
this指向window
this===window