这篇文章咱们来理解下js中的
this
关键字es6
在开始以前,咱们先定义几个规则面试
.
的方式new
的方式apply
,call
, bind
的方式
this
指向的就是调用方法的对象浏览器
let obj = {
name: 'len',
sayName: function() {
console.log(this)
}
}
obj.sayName() // { name: 'len', sayName: [Function: sayName] }
复制代码
this
指向的就是新建立的对象,咱们都知道,使用new
关键字的时候,会建立一个新的对象bash
let obj = {
name: 'len',
sayName: function() {
console.log(this)
}
}
new obj.sayName() // sayName {}
复制代码
这时候,
this
指向的就是调用bind,apply,call方法的第一个参数(下面例子中的obj
)babel
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() // {}
复制代码
var name = 'window'
let object = {
name: 'len',
sayName: function() {
return function() {
return this.name
}
}
}
console.log(object.sayName()()) // window
复制代码
上面为何打印window呢?咱们拆开来看app
let firsr = object.sayName()
first() // 这是做为单独函数调用的,也是就是上面的'规则4',因此this天然就指向window了
复制代码
箭头函数没有本身的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"
复制代码
咱们将上面的改动一下ui
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仍是挺好理解。只要本身用心去理解,相信你能够作到的。好了,就到这了,若是以为文章有什么问题,能够在下面留言探讨下。毕竟都是在学习,没有不出错的。谢谢理解!