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作用域详解——针对初学者
- JavaScript中的this,call,apply使用及区别详解
- 详解JavaScript中的this
- JavaScript中this的用法详解
- 详解Javascript 中的this指针
- 详解JavaScript中的this
- 详解JavaScript中的this
- this详解:JAVASCRIPT中的this到底是谁?
- 详解javascript中的this对象
- 详解Javascript 中的this指针
- JavaScript中this详解
- Javascript中this对象详解
- JavaScript中this的用法详解
- JavaScript中的This详解
- JavaScript之this详解(包含部分apply、cal解释)
- 详解 JavaScript 中的 this
- this详解:JAVASCRIPT中的this到底是谁?
- javascript中this的使用详解
- this详解:JAVASCRIPT中的this到底是谁?
- 详解JavaScript中this的指向问题