this指向问题的几条规则
1.函数预编译过程this--------------------window
2.全局作用域里this------------- window
3.call/apply 可以改变函数运行时this指向
4.obj.func(); func()里面的this指向obj -----------------调用this指向谁、
5.new构造的函数 this代表的是函数体内部
普通函数
// 普通函数调用this指向window
{
var num1=1;
function f1() {
this.num1=2; //这一步实际上改了num1的值
console.log(this); //window
console.log(this.num1); //2
}
f1();
console.log(num1); //2
console.log(this.num1); //2
}
构造函数
{
//构造函数:this指向的是实例化对象,原型对象里面的方法也是指向实例化对象
var num=1; //这里说一下 如果改成let声明就不行了 let声明的变量不属于window
function F1() {
this.num=2;
console.log(this);
console.log(this.num);
}
F1.prototype.run = function () {
console.log(this);
console.log(this.num);
}
let a = new F1(); //F1 2
a.run(); //F1 2
console.log(this.num); //1
}
对象方法调用
{
// 对象方法调用:this指向的是方法所属对象
var num=1
var obj = {
num:2,
run: function () {
console.log(this); //obj{run: ƒ}
console.log(this.num); //2
}
}
obj.run()
}
事件绑定方法
<button>点击</button>
{
//事件绑定方法:this指向的是绑定事件的对象
var btn = document.querySelector('button')
btn.onclick = function () {
console.log(this) //<button>点击</button> 返回该dom
}
}
定时器方法 this指向window
{
// 定时器方法:this指向的是window
var num=1;
setTimeout(function () {
console.log(this);
console.log(this.num);
}, 0);
setInterval(function () {
console.log(this);
console.log(this.num);
}, 1000);
// 输出结果为window 1
}
立即执行函数this指向window
{ // 立即执行函数:他和普通函数一样,this指向的window
(function () {
console.log(this)
})()
//输出结果为window
}
ES6中的箭头函数
//普通箭头函数
const funJ = () => {
console.log(this);
}
funJ(); //window
对象里的箭头函数 this指向
var num=1;
let obj={
num:2,
fun:()=>{
console.log(this.num);
}
}
obj.fun(); //1
function Obj() {
// var this=Object.create(Obj.prototype) new()的时候相当于在函数体创建了一个this对象里面放的就是原型链
this.id = 2333;
this.test = () => console.log(this.id);
}
var obj2 = new Obj(); //{id,test}
obj2.test(); //最后的结果是2333
var count = 12;
let show = {
count: 1,
fun:function(){
console.log(this.count); //1
setTimeout(function (){
console.log(this) //show
console.log(this.count) //12
}, 2000);
setTimeout(() => {
console.log(this) //window
console.log(this.count) //1
}, 2000);
function bbb(){
console.log(this); //window
console.log(this.count) //12
}
bbb();
const ccc=()=>{
console.log(this); //show
console.log(this.count) //1
}
ccc();
}
}
show.fun()
例子1:
// 分别用con()运行和 new con()运行的结果
var num = 123;
function con() {
this.num = 234; //直接全局调用 this指向window 即window.num=234 此时num已经改变
console.log(num)
}
con() //234
var num1 = 123;
function con1() {
// var this=Object.create(con.prototype) new()的时候相当于在函数体创建了一个this对象里面放的就是原型链
this.num1 = 234;
console.log(num1) //123
console.log(this.num1) //234
}
new con1(); //123
例子2:
var a = 5;
function test() {
a = 0;
console.log(a); //0
console.log(this.a); //5
var a;
console.log(a); //0
}
test();
var a = 5;
function test() {
a = 0;
console.log(a); //0
console.log(this.a); //undefind
var a;
console.log(a); //0
}
new test();
例子3:
<script>
var name = '222';
var a = {
name: '111',
say: function () {
console.log(this.name);
}
}
var fun = a.say;
fun(); //222
a.say(); //111
var b = {
name: '333',
say: function (fun) { //
fun(); //执行 没有人调用 this还是指向window 3题还是222
}
}
b.say(a.say); //222
b.say = a.say;
b.say(); //333
</script>