一、什么是this?
定义:this解析器在调用函数时传递给函数的一个参数,this指向的是一个对象,这个对象我们称为函数指向的上下文对象,根据函数的调用方式不同(跟创建方式无关),this会指向不同的对象。
二、this的指向
函数的不同调用方式决定了this 的指向不同
1、普通函数
function foo(){
console
.log(this);
}
foo();
结论:普通函数中this指向window
2、对象
var o
= {
sayHi
: function() {
console
.log(this);
}
}
o
.sayHi();
结论:对象中 this指向的是对象 o
3、构造函数
function Animal(type
, name
, color
, eat
) {
console
.log(this);
this.type
= type
;
this.name
= name
;
this.color
= color
;
this.eat
= eat
;
this.do = function() {
}
}
var dog
= new Animal('哺乳动物', '狗', '黑色', function() {
console
.log('喜欢吃骨头')
});
var fash
= new Animal('水生动物', '猫', '黑白色', function() {
console
.log('喜欢吃虾米')
});
console
.log(dog
);
console
.log(fash
);
dog
.eat();
fash
.eat();
dog
.do();
fash
.do();
总结:构造函数中this指向的是构造函数(new)所创建的对象
4、绑定事件函数
<body
>
<button
class="btn">点击按钮
</button
>
<script
>
var btn
= document
.querySelector('.btn');
btn
.onclick = function(){
console
.log(this);
}
</script
>
</body
>
总结:绑定事件函数中this的指向:[触发事件的元素],不是绑定事件的元素
5、定时器函数
window
.setTimeout(function() {
console
.log(this);
}, 1000);
总结: 定时器函数中this的指向的是window
6、立即执行函数
(function() {
console
.log(this);
})();
总结:立即执行函数中this的指向是window
三、this的原理
原理一: [与函数调用结合]: 当一个函数在执行的时候,就会创建一个上下文对象,[会产生局部作用域],上下文对象中,函数是被谁调用,在哪里调用的,参数是什么等信息;this就是记录的一个属性,在函数被调用时产生。原理二: [结合作用域看this]: 问题:为什么return返回为对象、数组、函数。this就不指向实例化的对象;函数本身不能作为构造函数,new类似失效。创建一个对象,就是将构造函数的作用域赋给了新对象;所以this 指向了这个对象,return {}, [],function 之后;改变了作用域,作用域赋值给了 {}、function、[] ,所以this指向{}、[]、function。
四、改变this的指向
1、call
<script
>
var name
= '周超';
function foo() {
console
.log(arguments
);
var name
= '刘玉才';
console
.log(this.name
);
}
var wjh
= {
name
: '网鱼行',
foo
: foo
}
var fei
= {
name
: "宇飞",
foo
: foo
,
cname
: this.name
}
var yuAng
= {
name
: '虞昂',
foo
: foo
}
foo();
wjh
.foo();
fei
.foo();
foo
.call(fei
,'我就是我,一个独立花朵',12);
foo();
</script
>
2、apply
<script
>
var name
= '周超';
function foo() {
console
.log(arguments
);
var name
= '刘玉才';
console
.log(this.name
);
}
var wjh
= {
name
: '王雨行',
foo
: foo
}
var fei
= {
name
: "宇飞",
foo
: foo
,
cname
: this.name
}
var yuAng
= {
name
: '虞昂',
foo
: foo
}
yuAng
.foo
.apply(window
,[1,2,43,4]);
</script
>
3、bind
<script
>
var name
= '周超';
function foo() {
console
.log(arguments
);
var name
= '刘玉才';
console
.log(this.name
);
}
var wjh
= {
name
: '王雨行',
foo
: foo
}
var fei
= {
name
: "宇飞",
foo
: foo
,
cname
: this.name
}
var yuAng
= {
name
: '虞昂',
foo
: foo
}
yuAng
.foo
.bind(window
)('1', 2, 3)
</script
>
五、如何判断this的指向?
如何判断this指向? 1、this在那个作用域中
全局:this指向的是windowfunction 函数体中
2、函数执行
看是否有call apply bind,若有。参数一是谁,this的指向就是谁。看是否是事件绑定函数,若是。this的指向就是触发事件的元素。调用函数是否是new,若是构造函数。this的指向是new实例化的对象。若以上都不满足,通用规律,谁调用它this的指向就是谁。
小示例
var name
= '滚滚滚';
var obj
= {
name
: '于飞',
cname
: this.name
,
say
: function() {
console
.log(`${this.name}说'于飞好帅呀!!!'`);
}
}
var say
= obj
.say
;
say();
var lzr
= {
name
: '李宗仁',
say
: function() {
console
.log(`${this.name}说:我长得好帅呀`);
}
}
lzr
.say
.call(obj
);
lzr
.say
.apply(this);