几个月之前就想要写一些博客,记录本身的学习历程,但因为各类缘由,没能动工,2019的第一个月即将过去,今天终于下定决心抓住一月的尾巴,勤奋一把,激励本身在2019能有所收获。因此这第一篇,就从面试常见的考点this指向
开始吧。面试
总的来讲,咱们始终要牢记的一句话就是:this始终指向最终调用它的那个对象数组
function demo () {
var a = '这是第一个demo的a'
console.log(this)
console.log(this.a)
}
demo()
// window
// undefined
复制代码
为何此处this.a是undefined呢?由于咱们能够把demo当作window.demo,window对象并无a这个属性,因此是undefined。若是但愿打印出'这是第一个demo',能够将代码改成以下示例:bash
function demoUpdate () {
this.a = '这是第一个demo的a'
console.log(this)
console.log(this.a)
}
demoUpdate()
// window
// 这是第一个demo的a
复制代码
var obj = {
a: '这是第二个demo的a',
func: function () {
console.log(this)
console.log(this.a)
}
}
obj.func()
// 指向obj
// 这是第二个demo
复制代码
function Constructor () {
var a = '这是第三个demo的a'
this.a = '这是第三个demo的b'
console.log(this)
console.log(this.a)
}
var func = new Constructor()
// 指向Constructor的实例对象
// 这是第三个demo的b
复制代码
为何此处的this.a指向的倒是'这是第三个demo的b',而不是a呢?这就涉及到构造函数的继承问题了,这里用var a 声明的a在Constructor的实例对象,也就是func中实际上并不存在,只有this.a声明的这个a对象才被func对象继承,存在于func中,因此当打印this.a时,打印的就是'这是第三个demo的b'app
var obj = {
a: '这是第四个demo的外层a',
child: {
a: '这是第四个demo的内层a',
func: function () {
console.log(this)
console.log(this.a)
}
}
}
obj.child.func()
// 指向obj.child
// 这是第四个demo的内层a
复制代码
function Constructor () {
this.a = '这是第五个demo的a'
return {}
}
var b = new Constructor
console.log(b.a) //undefined
复制代码
由于此时b指向的是Constructor生成的实例对象,而这个对象是个空对象,没有a属性函数
function Constructor () {
this.a = '这是第六个demo的a'
return function () {}
}
var b = new Constructor
console.log(b.a) // undefined,此时b指向的是Constructor的新的实例对象,也就是function () {}
复制代码
再看return的不是对象的状况学习
function Constructor () {
this.a = '这是第七个demo的a'
return 1
}
var b = new Constuctor
console.log(b.a) // 这是第七个demo的a
复制代码
此时b指向的是新生成的Constructor的实例对象,这个实例对象的a属性即为:这是第七个demo的aui
function Constructor () {
this.a = '这是第八个demo的a'
return undefined
}
var b = new Constructor
console.log(b.a) // 这是第八个demo的a,理由同上
复制代码
function Constructor () {
this.a = '这是第九个demo的a'
return null
}
var b = new Constructor
console.log(b.a) // 这是第九个demo的a
复制代码
首先看一个没有改变this指向时的例子this
var obj = {
a: '这是第十个demo的a',
func1: function () {
console.log(this.a)
},
func2: function () {
setTimeout( function () {
this.func1()
}, 1000)
}
}
obj.func2() // this.func1 is not a function
复制代码
为何此处报错而没有打印‘这是第十个demo的a’呢?由于当调用obj.func2时,func2中的setTimeout函数实质上是调用window对象的setTimeout函数,this指向window,而window对象没有func1这个属性,因此报错spa
箭头函数中没有this绑定,必须经过做用域链决定this的值,若是箭头函数被非箭头函数包含,则this指向最近的一层非箭头函数的this,不然,this为undefinedcode
var obj = {
a: '这是第十一个demo的a',
func1: function () {
console.log(this.a)
},
func2: function () {
setTimeout(() => {
this.func1()
}, 1000)
}
}
obj.func2() // 这是第十一个demo的a
复制代码
var obj = {
a: '这是第十二个demo的a',
func1: function () {
console.log(this.a)
},
func2: function () {
var that = this
setTimeout(function() {
that.func1()
}, 1000)
}
}
obj.func2() // 这是第十二个demo的a
复制代码
首先区分这三个函数的区别: call和apply改变this的指向后当即执行,而bind仅绑定this的指向,并不当即执行,返回改变this指向后的函数
call和bind的参数能够有多个,第一个参数为绑定的this的指向,后面的参数为传入函数的参数
apply只有两个参数,第一个参数为绑定的this的指向,第二个参数为包含传入函数的参数的数组
以上内容为我本身记录的知识点,若是后面有补充的,我会继续添加,此博客仅作记录知识点使用,如有幸被大佬们指点,不对的还烦请指正。