认识this
Js
使用的是静态作用域,即作用域和代码定义的有关,和代码执行无关。不过我们的this
正好和它们相反,在js
中,this
的值是根据执行位置决定的,通俗来说就是this
的值取决与你如何调用这个函数,而不是函数定义所在的位置。
this的指向
1.在最外层的作用域中this
指向的是 window
<script>
console.log(this)
</script>
2.定时器中的this
指向的是 window
<script>
setTimeout(function () {
console.log(this)
}, 3000)
setInterval(() => {
console.log(this)
}, 1000);
</script>
3.一般函数中使用
在一个普通的函数中,this
的值在浏览器中是window
。如果是在严格模式下,一般的函数调用中 this
的值是 undefined
。
//默认情况下为非严格模式
<script>
function add() {
console.log(this)
}
add()
</script>
4.立即执行函数中的this
指向的是 window
<script>
(function(){
console.log(this)
})()
</script>
5.DOM事件绑定的处理函数中的 this
指向的是触发该事件的DOM对象。
<script>
document.querySelector('div').onclick = function () {
console.log(this)
}
</script>
6.作为对象的方法如果函数作为对象的方法,也就是说调用方法是对象.方法()
,那么这个时候所执行的函数中this
就是这个对象的引用。
<script>
let sx = {
name: '二狗子',
age: 19,
run: function () {
console.log(this.name)
}
}
sx.run()
</script>
7.构造函数中的this就是在函数作为构造函数使用时,this
指向的是新创建的对象。
<script>
function Sx() {
this.name = '二狗子',
this.age = 19,
this.run = function () {
console.log(this.age)
return 888
}
console.log(6666)
}
let a = new Sx()
// 创建一个空对象
// 调用Sx函数
// this指向该对象
console.log(a.name)
console.log(a.run())
</script>
8.原型对象方法中的this
原型对象中的this
,指向的也是新创建的对象。
<script>
function Mouse(){
this.name = '二狗子'
this.run = function(){
console.log(this.name)
}
}
let gouObj= new Mouse()
// gouObj.run()
function Cat(x){
this.name = x
}
Cat.prototype = gouObj
let smallCat = new Cat('我是猫')
smallCat.run()
</script>
//打印出来的是:我是猫
9.箭头函数中没有this
函数的调用和改变this指向
1.call()方法的两个作用
(1)正常的调用和传参
<script>
function sx(age){
console.log(age)
console.log(this)
}
sx(18)
sx.call(null,19)
</script>
(2)改变this指向和传参
<script>
function sx(age){
console.log(age)
console.log(this)
}
let a = {
name:'二狗子',
age:22
}
sx.call(a,19)
</script>
扩展:使用call()
实现继承
<script>
function Cat(x, y) {
this.name = x;
this.age = y;
this.run = function () {
console.log('跑得快');
};
this.catchMouse = function () {
console.log('我會抓老鼠');
}
console.log(6666)
}
function Tiger(a, b) {
this.name = '虎';
this.run = function () {
console.log('跑得更快');
}
Cat.call(this, a, b);
// Cat.apply(this, [a, b]);
}
// new 构造函数发生的过程:
// 创建一个空对象
// 将构造函数内部的this指向该对象
// 执行构造函数里面的代码
// 返回该对象
var t2 = new Tiger('大花猫', 18);
t2.catchMouse();
t2.run()
console.log(t2.name);
console.log(t2.age);
</script>
2.apply()
apply()
方法和call()
方法的作用一模一样,区别只是传参的时候,传参方式不同,apply()
传参的时候,需要将参数写入到一个数组中
3.bind()
方法和前面说的apply()
方法call()
方法一样,可以改变this
指向,不过它不会自动调用函数,不过它会返回一个经过改造后的函数的拷贝。
function xx(age, sex){
console.log(this);
console.log(this.name);
console.log(age);
console.log(sex);
}
var obj = {name: '书生'};
// 并不会调用函数
xx.bind(obj, 18, '男');
// 可以改变this指向
// 可以返回改变this后的函数的拷贝
// 返回值是xx函数的一个拷贝
// 这个拷贝 是个经过改造后的xx
// 改造的内容:将xx函数中this指向obj对象
// 传参方式和call一样
var X = xx.bind(obj, 18, '男');
// 手动调用
X();