this:上下文会根据执行环境变化而发生指向的改变
1.单独的this,指向的是window这个对象
alert(this);//this->window
2.全局函数中的this
function demo(){
alert(this);//this->window
}
在严格模式下,this指向undefined
function demo(){
'use strict'
alert(this);//undefined
}
3.函数调用的时候,前面加上关键字new,所谓构造函数就是通过这个函数生成一个新对象,这时,this就是指向这个对象。
function demo(){
alert(this);//this->window
this.teststr='this is a test';
}
let a= new demo();
console.log(a.teststr);// this is a test
4.用call和apply的方式调用函数
function demo(){
alert(this);
}
demo.call("abc");//this->abc
demo.call("null");//this->window
demo.call("undefined");//this->window
5.定时器中的this,指向的是window
setTimeout(function (){
alert(this);//this->window
},1000)
严格模式下也指向window
6.绑定元素事件,事件触发后,执行的函数中的this,指向的是当前元素
window.onload=function (){
let $btn=document.getElementById('btn');
$btn.onclick=function (){
alert(this);//this->$btn当前触发事件的元素
}
}
7.函数调用时如果绑定了bind,那么函数中的this指向了bind中绑定的元素
window.onload=function (){
let $btn=document.getElementById('btn');
$btn.addEventListener('click',function (){
alert(this);//window
}.bind(window))
}
8.对象中的方法,该方法被那个对象调用了,那么方法中的this就指向该对象
let name='finget';
let obj={
name:"FinGet",
getName:function (){
alert(this.name);
}
}
obj.getName();//FinGet
let fn=obj.getName;
fn();//finget this->window 这段代码在全局环境中执行 this->window
笔试题:
var x=20;
var a={
x:15,
fn:function (){
var x=30;
return function (){
return this.x;
}
}
}
console.log(a.fn())//function (){return this.x;}
console.log((a.fn())());//20 a.fn()返回的是一个函数 ()()是自执行表达式 this->window
console.log(a.fn()());//20 a.fn()相当于在全局定义了一个函数,然后再自己执行 this->window
console.log(a.fn()()==(a.fn())());//ture
console.log(a.fn().call(this)); 20 这段代码在全局环境下执行 this->window
console.log(a.fn().call(a));//15 this->a
对象中嵌套超过一级以上的函数,this指向都是window
var obj = {
x: 456,
fn: function () {
console.log('fn', this) // {x: 456, fn: ƒ}
var f1 = function () {
console.log('fn.f1', this) // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
console.log(this.x) // undefined
var f2 = function () {
console.log('fn.f2', this) // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
}
f2()
}
f1()
}
}
obj.fn()
构造函数中。嵌套超过一级以上的函数,this指向都是window
var Person = function () {
this.name = 'linlif'
this.fn = function () {
console.log('fn', this) // {name: "linlif", fn: ƒ}
var f2 = function () {
console.log('f2', this) // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
var f3 = function () {
console.log('f3', this) // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
}
f3()
}
f2()
}
}
var person = new Person()
person.fn()
调用函数的三种方法:
直接调用;
通过call()调用;
通过apply()调用;
这是一个有趣的题:
let Obj = function (msg) {
this.msg = msg
this.shout = function () {
alert(this.msg)
}
this.waitAndShout = function () {
// 隔5秒后执行上面的shout方面
setTimeout(function () {
let self = this
console.log(self)//obj 如果不用call替换this指针 namesetTimeout里面的所有指针都将是window
return function () {
self.shout();
console.log(this,self)//window obj
}
}.call(this), 1000)//本来setTimeout里面的this指针,指向window,
// 但是这里通过使用call将this指针替换成了当前执行对象,
// 并且在计时器的回调函数里一开始就把this指针接受到变量self里面
//因为这个回调函数返回的函数,相当于在全局定义了一个函数,所以这个返回的函数就指向window
return this
}
}
let obj = new Obj('msg')
obj.waitAndShout()