您的位置:首页 > Web前端 > JavaScript

javascript中的this详解

2018-03-01 21:52 561 查看

概述

首先我们扫一下盲:
this
在javascript这门语言中只有在函数内部才有被讨论的价值。

this的指向应该始终由调用方来决定,而不是由定义方决定
。当然我们这篇文章是针对ES5,至于ES6中箭头函数的this指向由定义方决定这种问题我们这里不进行讨论

应用场景分析

1、普通函数调用

普通函数的调用,在非严格模式下this指向window,当然严格模式下修复了指向window这个bug,我们在这儿不在赘述,因为这不是我们这次讨论的范畴。

var name = 'ice';
function foo() {
this.age = 18;
return this.name;
}
foo(); // ice
console.log(age); // 18


2、对象方法调用

当作为对象方法调用,this通常指向该对象

var name = 'ace';
function getName() {
return this.name;
}
var obj = {
name: 'ice',
getName: getName
}
obj.getName(); // ice


也会有一些“对象方法的调用并未指向该对象”的情况,其实不然,新对象的方法调用时并未继承旧对象的作用域,所以this还是指向新对象,如下:

// 例1
function getName() {
return this.name;
}
var obj = {
name: 'ice',
getName: getName
}
var _obj = {
name: 'ace',
getName: obj.getName
}
_obj.getName(); // ace

// 例2
document.body.onclick = obj.getName;
// 当点击body元素输出:undefined,此时this指向body元素


3、构造函数被调用

作为构造函数时,this指向该构造函数实例化的对象。当然也有奇葩的写法来扰乱我们的视线,即使这样并不会改变this的指向,只是实例的作用域问题,如下例2:

// 例1
function Person() {
this.name = 'ice';
}
var person = new Person();
console.log(person.name); // ice

// 例2
function Person() {
this.name = 'ice';
return {name: 'ace'}
}
var person = new Person();
console.log(person.name); // ace


4、apply、call、bind做主了

apply和call可以在调用期间改变this指向,而bind可以在函数定义期间就可以改变this指向:

// 例1
function getName() {
return this.name;
}
var obj = {
name: 'ice',
getName: getName
}
obj.getName.call({name: 'ace'}) // ace
/**
* obj.getName.apply({name: 'ace'}) // ace
*/

// 例2
function getName() {
return this.name;
}
var obj = {
name: 'ice',
getName: getName.bind({name: 'ace'})
}
obj.getName() // ace


5、setTimeout

我们最后来说一个使用场景很多,但this定位很尴尬的使用方式setTimeout,当作为setTimeout的回调函数时,this指向window(当然是非严格模式),不过我们可以用bind或者参数传递等方法实现功能(例3):

// 例1
var name = 'ice';
setTimeout(function() {
console.log(this.name); // ice
}, 1000)

// 例2
function showTagName() {
console.log(this);
console.log(this.tagName);
}
var obj = {
tagName: 'OBJ',
showTagName: showTagName
}
document.body.onclick = function() {
setTimeout(showTagName, 1000)
// 1、window。2、undefined
}

// 例3
document.body.onclick = function() {
setTimeout(showTagName.bind(this), 1000)
// 1、body元素。2、"BODY"
}


至此我们对于javascript这门语言的
this
指向有了一个比较清晰的理解了,其实导致this指向这么杂乱的主要原因是javascript之父(布兰登·艾奇(Brendan Eich,1961年~))只用相当短的时间(10天)创造了这门语言,已经很伟大了,有诸如this这种问题不可避免。

ES6、ES7、ES8、node等都在完善javascript,它依然是当下最流行的脚本语言,所以好好撸吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  javascript this