js this 指向
this 概念: 1.在js中,this 是一个指针型变量,动态指向当前函数的运行环境 2.在不同的场景中调用同一个函数,this的指向也可能会发生变化,但是它永远指向其所在函数的真实调用者;如果没有调用者,就指向全局对象window。
普通函数:关于this,谁调用就指向谁,没有调用者,就指向全局对象window。
[箭头函数]:箭头函数的this指向于函数作用域所用的对象。
一、全局环境下的this指向
在全局[作用域]下,this始终指向全局对象window,无论是否是[严格模式]
二、函数内的this
1. 严格模式下:
function test(){
console.log(this)
}
test(); // underfined
window.test() //window
2. 非严格模式下:
function test(){
console.log(this)
}
test(); // window
window.test() //window
三、对象中的this
对象内部方法的this指向调用这些方法的对象,也就是谁调用就指向谁。 1.一层对象
let objTest = {
name: '1',
skill: function(){
name: '2',
console.log(this.name)
}
}
console.log(objTest.skill()) // 1 this 指向 objTest
2.二层对象
let objTest = {
name: '1',
skill: function(){
name: '2',
console.log(this.name)
},
obj2: {
name: '33',
skill2: function(){
name: '44',
console.log(this.name)
},
}
}
console.log(objTest.obj2.skill2()) // 33 this 指向 obj2
总结:1.函数的定义位置不影响其this 指向,this 指向只和调用函数的对象有关 2.多层嵌套的对象,内部方法的this指向离被调用函数最近的对象。
四、[箭头函数]中的this
箭头函数:this指向于函数作用域所用的对象。
箭头函数的重要特征: 1.箭头函数中没有this和arguments,是真的没有! 2.箭头函数没有自己的this指向,它会捕获自己定义所处的外层执行环境,并且继承这个this值,指向当前定义时所在的对象。箭头函数的this指向在被定义的时候就确定了,之后永远都不会改变。即使使用call()、apply()、bind()等方法改变this指向也不可以。
var isObject = {
a: 'hhh',
function: ()=> {
console.log('对象: ' , this)
}
}
isObject.function(); //window
声明的是全局变量isObject,this指向箭头函数所在全局作用域的对象,即window对象。
var obj1 = {
name: 'seven',
getName(){
console.log(this)
return this.name
}
}
console.log('obj1----', obj1.getName())
{name: 'seven', getName: ƒ} getName: ƒ getName()name: "seven"[[Prototype]]: Object
obj1---- seven
总结:
第一个例子中,this
指向的是箭头函数所在的上下文,即全局对象 window
,因为箭头函数没有自己的 this
,它的 this
继承自外层的上下文。
第二个例子中,this
指向的是调用 getName
方法的对象 obj1
。因为 this
的指向是在函数被调用时确定的,而调用 getName
方法时是通过 obj1.getName()
的方式调用的,所以 this
指向的是 obj1
。
五、[构造函数]中的this
构造函数中的this是指向实例。
// 构造函数的this, 构造函数的函数名首字母大写,便于区分普通函数
function Person(name, sex, age){
this.name = name;
this.sex = sex;
this.age = age;
}
// 构造函数中实例必须用new 声明
let p = new Person('www', 'female', 18)
// 构造函数中的this指向构造函数下创建的实例。
六、原型链中的this
this这个值在一个继承机制中,仍然是指向它原本属于的对象,而不是从原型链上找到它时,它所属于的对象。
七、[改变this指向]的方法
- call() -
call(a, b, c)
方法接收三个参数,第一个是this指向,第二个,三个是传递给函数的实参,可以是数字,字符串,数组等类型的数据类型都可以。 - apply() -
apply(a, [b])
和call基本上一致,唯一区别在于传参方式,apply把需要传递给fn()
的参数放到一个数组(或者类数组)中传递进去,虽然写的是一个数组,但是也相当于给fn()
一个个的传递。
//call()的传参方式 fn.call(obj, 1, 2); //apply()的传参方式 fn.apply(obj, [1, 2]);
- bind()
bind(a, b, c)
:语法和call一模一样,区别在于立即执行还是等待执行,bind不兼容IE6~8- bind与call的唯一区别就是call直接改变函数test的指向,而bind是生成了一个新函数
test2()
,该函数改变了指向。
总结:1. 在对象方法中,this 指向调用该方法的对象。 2. 在构造函数中,this 指向正在创建的对象。 3. 在事件处理程序中,this 指向触发事件的元素。 4. 在箭头函数中,this 指向定义该函数时的上下文,而不是调用该函数时的上下文。
转载自:https://juejin.cn/post/7235906879624462396