Javascript 中this关键字的理解

1.javaScript语言精粹中分四类场景

  • 有对象就指向调用对象(箭头函数除外,箭头函数没有独立的this作用域,所以往外层走)
var myObject = {value: 2017};
myObject.getValue = function(){
    console.log(this.value); //2017
    console.log(this); //{value: 2017,[Function]}
    return this.value;
};
console.log(myObject.getValue); //2017

var a = {
    name: js;
    getName:function(){
        console.log(this);//a对象
        setTimeout(()=> {
            console.log(this);//a对象
            },0)
    }
}
  • 没调用对象就指向全局对象
var myObject = {value: 2017};
myObject.getValue = function(){
    var f = function(){
        console.log(this.value); //undefined
        console.log(this); //输出全局对象
    };
    f();
    return this.value;
};
console.log(myObject.getValue); //2017

f函数虽然定义在getValue函数体内,但实际上不属于getValue也不属于myObject,没绑定到任何对象上,所有当调用this指向全局变量
- 用new构造就指向新的对象
JS中通过new关键字调用构造函数,this绑定新的对象

var F = function(){
    this.value = 2017;
}

var myObject = new F();
console.log(myObject.value); //2017
  • 通过applycallbind来改变this的指向
    apply()方法接收两个参数,第一个函数运行的作用域,另一个是参数数组(arguments)
    call()方法第一个参数和apply()方法相同,只是其他的参数需要一一列出来
var myObject = {value: 2017};

var f = function(){
    console.log(this);
};

f(); //全局变量
f.apply(myObject); //{value: 2017}
f.call(myObject); //{value: 2017}

var newF = f.bind(myObject);
newF(); //{value: 2017}

2.普通函数,对象函数,定时器,构造函数,事件函数,call()/apply()

1.普通函数

var name = "js";
function demo(){
    var name = 'css';//在函数内部定义并声明的变量是局部变量
    console.log(this.name); //js
}
demo(); //window.demo(),只不过我们在平常写代码的时候会自动忽略掉。
//所以window是函数的调用者,this指向window,this下name属性的值就是全局变量
//所以输出的是全局变量 js,而不是局部变量 css

2.定时器

1.
setInterval(function(){
    var a = 2017;
    alert(this.a);
    },1000); //undefined,setInterval方法也属于window,因为window对象下没有a属性,因此浏览器每隔一秒弹出一次undefined提示框

2.
function Demo(){
    this.a = 2017;
    setInterval(this.show,1000);
}
Demo.prototype.show = function(){
    alert(this.a);
}
var demo = new Demo();
demo.show(); //第一次弹出2017,之后每一秒弹出undefined
//原因在this.show代表了Demo.prototype.show的函数体,this指向Demo,所以第一次弹出2017//之后延迟定时器开始工作,定时器时钟到达之后this指向windowwindow下没有a属性,所以每隔一秒弹出undefined

3.对象方法

var myObject = {
    name: "js",
    f: function(){
        alert(this.name);
    }
}
var demo = myObject.f();
demo(); //js,如果一个对象中的方法有this,上一级调用这个方法,this指向上一级对象

4.构造函数

function Person(name,age){
    this.name = name;
    this.age = age;
    function f(){
        alert('JavaScript');
    }
    // return f;
}
var per = new Person('js',2017);
console.log(per); //new关键字在内存中开辟了新的内存空间,返回首地址的值,并将this指向开辟的内存空间上,输入per对象,如果取消return注释,输出f函数体

5.事件函数

<body>
    <button id='btn'>Click</button>
</body>
<script type="text/javascript">
    var btn = document.querySelector('#btn');
    btn.onclick = function(){
        function fn(){
            alert(this); //弹出window,如果事件函数中还有其他的函数,this还是指向window
        }
        fn();
    }
</script>

如果想修改this的指向,可以用以下两种方法

在onclick函数中将this指针赋值给一个变量var _this = this; 然后fn()函数调用_this变量就可以指向button对象了
将下面执行的fn函数改为fn.call(this);
来改变this指向 apply函数类似

总结:
1. 构造函数中this就是即将new出来的对象
2. 全局普通函数this指向全局变量window
3. 函数作为对象的一个属性,并且作为对象的一个属性被调用(obj.fn();),this指向该对象(带括号就是对函数的调用,得到返回值)
4. 属性函数被赋值给另一个变量,并没有作为一个属性被调用,this指向windos 就像var fn1 = obj.fn; fn1();只是一个引用,对象到fn1了成全局的
5. 在对象函数属性中还有函数时,这个函数就是一个普通函数,this指向window

还可以参考判断最简单的JS中this的指向

猜你喜欢

转载自blog.csdn.net/u013270347/article/details/80336148
今日推荐