This in JavaScript
栏目: JavaScript · 发布时间: 5年前
内容简介:这篇文章我们来理解下js中的在开始之前,我们先定义几个规则
这篇文章我们来理解下js中的 this
关键字
在开始之前,我们先定义几个规则
-
函数作为方法调用, 也就是用
.
的方式 -
用
new
的方式 -
用
apply
,call
,bind
的方式 - 函数作为自由函数调用
第一种规则,函数作为方法调用
this
指向的就是调用方法的对象
let obj = { name: 'len', sayName: function() { console.log(this) } } obj.sayName() // { name: 'len', sayName: [Function: sayName] } 复制代码
第二种规则
this
指向的就是新创建的对象,我们都知道,使用 new
关键字的时候,会创建一个新的对象
let obj = { name: 'len', sayName: function() { console.log(this) } } new obj.sayName() // sayName {} 复制代码
第三种规则
这时候, this
指向的就是调用bind,apply,call方法的第一个参数(下面例子中的 obj
)
function fn() { console.log(this) } let obj = { value: 5 } let boundFn = fn.bind(obj) boundFn() // { value: 5 } fn.call(obj) // { value: 5 } fn.apply(obj) // { value: 5 } 复制代码
第四种规则
在浏览器中, 这时候 this
指向的就是就是window对象
function foo() { console.log(this) } foo() // Window{} 复制代码
规则中的组合情况
const obj = { value: 'hi', printThis: function() { console.log(this) } } const print = obj.printThis // 规则1,this指向的就是obj obj.printThis() // {value: 'hi', printThis: f} // 规则4,this指向的就是Window print() // Window {} 复制代码
const obj1 = { value: 'hi', printThis: function() { console.log(this) } } const obj2 = {value: 17} // 规则1和3的组合, 规则3的优先级大于规则1 obj1.print.call(obj2) // {value: 17} // 规则1和规则2的组合,规则2的优先级大于规则1 new obj1.print() // {} 复制代码
闭包中的this
var name = 'window' let object = { name: 'len', sayName: function() { return function() { return this.name } } } console.log(object.sayName()()) // window 复制代码
上面为什么打印window呢?我们拆开来看
let firsr = object.sayName() first() // 这是作为单独函数调用的,也是就是上面的'规则4',所以this自然就指向window了 复制代码
es6箭头函数的this
箭头函数没有自己的this,请看:
// es6 function foo() { setTimeout(() => { console.log(this) }) } // es5 function foo() { var _this = this setTimeout(function() { console.log(_this) }, 1000) } foo() // Window{} new foo() // foo{} 这样就又回到了上面的规则了。 复制代码
上面es5代码是我用在线babel编译es6代码得到的。从上面我们可以看出,箭头函数是没有自己的this的,它实际上是保存了父级作用域的this,然后在箭头函数里面调用的都是父级作用域的this。也正是因为箭头函数没有this,所以自然而然我们就不能使用call,apply,bind来改变this的指向了。
最后,来个面试题
class Animal() { constructor(type) { this.type = type } say(val) { setTimeout(() => { console.log(this); console.log(this.type + " says " + val); }, 1000) } } // es6的class里面的方法都是定义在prototype上的 console.log(Animal.prototype) // 在浏览器中 {constructor: f, say: f} const animal = new Animal('animal') animal.say('hi') // 1s later console log "Animal{type: 'animal'}" and "animal says hi" 复制代码
我们将上面的改动一下
class Animal() { constructor(type) { this.type = type } say(val) { // 这里没有使用箭头函数,这里的setTimeout形成了一个闭包,this指向的是window setTimeout(function() { console.log(this); console.log(this.type + " says " + val); }, 1000) } } const animal = new Animal('animal') animal.say('hi') // Window {} / undefined says hi 复制代码
总结: js中的this还是挺好理解。只要自己用心去理解,相信你可以做到的。好了,就到这了,如果觉得文章有什么问题,可以在下面留言探讨下。毕竟都是在学习,没有不出错的。谢谢理解!
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。