难点:this指向问题在这里插入图片描述
<button>点击</button>
<script>
// 函数的不同调用方式决定了this 的指向不同
// 1. 普通函数 this 指向window
function fn() {
console.log('普通函数的this' + this);
}
window.fn();
// 2. 对象的方法 this指向的是对象 o
var o = {
sayHi: function() {
console.log('对象方法的this:' + this);
}
}
o.sayHi();
// 3. 构造函数 this 指向 ldh 这个实例对象 原型对象里面的this 指向的也是 ldh这个实例对象
function Star() {};
Star.prototype.sing = function() {
}
var ldh = new Star();
// 4. 绑定事件函数 this 指向的是函数的调用者 btn这个按钮对象
var btn = document.querySelector('button');
btn.onclick = function() {
console.log('绑定时间函数的this:' + this);
};
// 5. 定时器函数 this 指向的也是window
window.setTimeout(function() {
console.log('定时器的this:' + this);
}, 1000);
// 6. 立即执行函数 this还是指向window
(function() {
console.log('立即执行函数的this' + this);
})();
</script>
<script>
const obj = { name: '张三' }
function fn() {
console.log("第一个",this);//Object
return () => {
console.log("第二个",this)//Object
}
}
fn.call(obj)();
//fn.call(obj);只输出第一个
//const resFn = fn.call(obj);//第一种情形
// resFn();
const obj2 = { name: '李四' }
function fn2() {
console.log("第三个",this);//Window
return () => {
console.log("第四个",this)//Window
}
}
//fn2();//只输出第三个
const res=fn2();//只输出第三个
console.log(res,typeof res);//return后面的内容,是function类型
res();
</script>
fn.call(obj)(); call方法改变了this指向
call() 方法调用一个对象。简单理解为调用函数的方式,但是它可以改变函数的 this 指向。
fun.call(thisArg, arg1, arg2, ...)
thisArg:在 fun 函数运行时指定的 this 值
arg1,arg2:传递的其他参数
返回值就是函数的返回值,因为它就是调用函数
因此当我们想改变 this 指向,同时想调用这个函数的时候,可以使用 call,比如继承
fn2();//只输出第三个
return后面的内容是作为返回值,res变量接收这个返回值(也就是return后面的箭头函数),再调用res();才会输出第四个。(注意)
**【补充】**箭头函数不绑定this关键字,箭头函数中的this,指向的是函数定义位置的上下文this。
有的箭头函数都没有自己的 this。 不适合定义一个 对象的方法。
当我们使用箭头函数的时候,箭头函数会默认帮我们绑定外层 this 的值,所以在箭头函数中 this 的值和外层的 this 是一样的。
原型对象(prototype)this指向
构造函数中的this 指向我们实例对象.
原型对象里面放的是方法, 这个方法里面的this 指向的是 这个方法的调用者, 也就是这个实例对象.
严格模式下 this 指向问题
以前在全局作用域函数中的 this 指向 window 对象。
严格模式下全局作用域中函数中的 this 是 undefined。(不一样)
以前构造函数时不加 new也可以调用,当普通函数,this 指向全局对象
严格模式下,如果 构造函数不加new调用, this 指向的是undefined 如果给他赋值则会报错(不一样)
new 实例化的构造函数指向创建的对象实例。
定时器 this 还是指向 window 。
事件、对象还是指向调用者。
1)单纯的函数调用
function test(){
this.x = 1;
console.log(this.x)//1
};
test();
console.log(this.x) ;//1
console.log('x' in window);//true
2)函数作为对象的方法调用
var test = {
a:1,
b:function(){
alert(this.a);
} //b:f引用
};
test.b();//结果为:1 test调用了函数b,this指向test
alert(this.a);//结果为:undefined window调用了alert函数,this指向 window而window里并没有a这个属性。