likes
comments
collection
share

js this 指向

作者站长头像
站长
· 阅读数 15

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指向]的方法

  1. call() - call(a, b, c)方法接收三个参数,第一个是this指向,第二个,三个是传递给函数的实参,可以是数字,字符串,数组等类型的数据类型都可以。
  2. apply() - apply(a, [b])和call基本上一致,唯一区别在于传参方式,apply把需要传递给fn()的参数放到一个数组(或者类数组)中传递进去,虽然写的是一个数组,但是也相当于给fn()一个个的传递。
//call()的传参方式 fn.call(obj, 1, 2); //apply()的传参方式 fn.apply(obj, [1, 2]);
  1. bind()
  • bind(a, b, c):语法和call一模一样,区别在于立即执行还是等待执行,bind不兼容IE6~8
  • bind与call的唯一区别就是call直接改变函数test的指向,而bind生成了一个新函数test2(),该函数改变了指向。

总结:1. 在对象方法中,this 指向调用该方法的对象。 2. 在构造函数中,this 指向正在创建的对象。 3. 在事件处理程序中,this 指向触发事件的元素。 4. 在箭头函数中,this 指向定义该函数时的上下文,而不是调用该函数时的上下文。