https://juejin.im/post/6844903496253177863
this 的指向
this永远指向最后调用它的那个对象
例1:
var name = "windowsName" function a() { var name = "Cherry" console.log(this.name) // windowsName console.log("inner:" + this) // inner:Window } a() console.log("outer:" + this) // outer:Window最后调用 a 的地方 a(),前面没有调用的对象 那么就是全局对象window,相当于是window.a()。(如果使用严格模式,全局对象是 undefined,会报错)
例2:
var name = "windowsName" var a = { name:"Cherry", fn:function() { console.log(this.name) // Cherry } } a.fn()函数fn是对象a调用的,所以打印的值就是a中的name的值。
例3:
var name = "windowsName" var a = { name:"Cherry", fn:function() { console.log(this.name) // Cherry } } window.a.fn()这里打印Cherry的原因也是因为“this永远指向最后调用它的那个对象”最后调用他的对象仍然是对象a
例4
var name = "windowsName" var a = { // name:"Cherry", fn:function() { console.log(this.name) // undefined } } window.a.fn()调用fn的是a对象,也就是说fn的内部的this是对象a,而对象a中并没有对name进行定义,就算a中没有name这个属性,也不会继续向上一个对象寻找 this.name,而是直接输出 undefined。
例5
var name = "windowsName" var a = { name:null, fn:function() { console.log(this.name) // windowsName } } var f = a.fn fn()这里虽然将a对象的fn方法赋值给变量f了,但是没有调用,所以fn()最后仍然是被window调用的。所以this的指向也就是window。
例5
var name = "windowsName" var a = { var name = 'Cherry' innerFunction() function innerFunction() { console.log(this.name) // windowsName } } fn()例7:
var name = "windowsName" var a = { name:"Cherry" func1:function() { console.log(this.name) } func2:function() { setTimeout( function() { this.func1() },100) } } a.func2() // this.func1 is not a function在不使用箭头函数情况下是会报错的,因为最后调用 setTimeout 的对象是 window,但是在 window 中并没有 func1 函数
箭头函数
箭头函数的this始终指向函数定义时的this,而非执行时。箭头函数中没有this绑定,必须通过查找作用域链来决定其值,如果箭头函数被非箭头函数包含,则this绑定在最近一层非箭头函数的this,否则,this为undefined
例8:
var name = "windowsName" var a = { name:"Cherry" func1:function() { console.log(this.name) } func2:function() { setTimeout( () => { this.func1() },100) } } a.func2() // Cherry在函数内部使用 _this = this
先将调用这个函数的对象保存在变量 _this 中,然后在这个函数中都使用 _this,这样 _this 就不会改变了
例9:
var name = "windowsName" var a = { name:"Cherry" func1:function() { console.log(this.name) } func2:function() { var _this = this setTimeout( function() { _this.func1() },100) } } a.func2() // Cherry在 func2 中先设置 _this = this,这里的this 是调用func2 的对象a,为了防止在 func2 中的 setTimeout 被 window 调用而导致在 setTimeout 中的 this 为 window。将this(指向变量a)赋值给一个变量 _this,这样在 func2中使用_this 就指向对象a了。
使用apply、call、bind 例 10:
// 使用apply var a = { name:"Cherry" func1:function() { console.log(this.name) } func2:function() { setTimeout( function() { this.func1() }.apply(a),100) } } a.func2() // Cherry例 11:
// 使用call var a = { name:"Cherry" func1:function() { console.log(this.name) } func2:function() { setTimeout( function() { this.func1() }.call(a),100) } } a.func2() // Cherry例 12:
// 使用bind var a = { name:"Cherry" func1:function() { console.log(this.name) } func2:function() { setTimeout( function() { this.func1() }.bind(a),100) } } a.func2() // Cherryapply和call的区别
基本类似 传参不同 call方法接收的是若干个参数列表,而apply接受的是一个包含多个参数的数组
例 13:
var a = { name:"Cherry" fn:function(a,b){ console.log(a+b) } } var b = a.fn b.apply(a,[1,2]) // 3例 14:
var a = { name:"Cherry" fn:function(a,b){ console.log(a+b) } } var b = a.fn b.call(a,1,2) // 3bind和apply、call的区别
bind()方法创建一个新的函数,当被调用时,将其this关键字设置为提供的值,在调用新函数时,在任何提供之前提供一个给定的参数序列。所以bind是创建一个新的函数,必须手动调用。
var a = { name:"Cherry" fn:function(a,b){ console.log(a+b) } } var b = a.fn b.bind(a,1,2)() // 3