js中this指向哪里

JavaScript 中的 this 指向是一个重要且复杂的概念,每次记了忘忘了记,自己实操下整个文档加深下印象
  • 全局环境中的this
js 复制代码
// 在浏览器中
console.log(this);  // Window 对象

// 在 Node.js中
console.log(this);  // {} 空对象
  • 函数中的this
js 复制代码
// 普通函数调用
function test() {
    console.log(this);  // 严格模式下是 undefined,非严格模式下是 Window
}
test();

// 对象方法调用
const obj = {
    name: 'obj',
    test: function() {
        console.log(this);  // 指向 obj 对象
    }
};
obj.test();

// 箭头函数
const obj = {
    name: 'obj',
    test: () => {
        console.log(this);  // 指向定义时的上下文,这里是 Window
    }
};
obj.test();
  • 构造函数中的this
js 复制代码
function Person(name) {
    this.name = name;  // this 指向新创建的对象
    console.log(this);
}

const p = new Person('John');  // Person { name: 'John' }
  • 事件处理函数中的this
js 复制代码
<body>
<button id="btn">点击</button>
    <script>
      const button = document.getElementById('btn');

      // DOM 事件
      button.addEventListener('click', function () {
        console.log(this); // 指向触发事件的dom元素
      });

      // 箭头函数作为事件处理函数
      button.addEventListener('click', () => {
        console.log(this); // 指向定义时的上下文,这里指向window
      });
    </script>
</body>
  • call、apply、bind改变this
js 复制代码
function test() {
    console.log(this.name);
}

const obj1 = { name: 'obj1' };
const obj2 = { name: 'obj2' };

// call
test.call(obj1);  // 'obj1'

// apply
test.apply(obj2);  // 'obj2'

// bind
const boundTest = test.bind(obj1);
boundTest();  // 'obj1'
  • 类中的this
js 复制代码
class Person {
    constructor(name) {
      this.name = name; // this 指向实例
    }

    sayName() {
      console.log(this.name); // 'john'
    }

    // 箭头函数方法
    sayNameArrow = () => {
      console.log(this.name); // 'john'
    };
}

const p = new Person('John');
p.sayNameArrow(); // 'John'
  • 定时器中的this
js 复制代码
const obj = {
    name: 'obj',
    test: function () {
      setTimeout(function () {
        console.log(this); // Window
      }, 1000);

      setTimeout(() => {
        console.log(this); // obj
      }, 1000);
    },
  };
  obj.test();
js 复制代码
//如果example是箭头函数,下面不论是否严格模式都指向window

function example() {
    console.log(this); // 严格模式下是undefined 非严格模式Window
    setTimeout(() => {
      console.log(this); // 严格模式下是undefined 非严格模式Window
    }, 0);
    setTimeout(function () {
      console.log(this); // Window
    }, 0);
}

example();
  • promise中的this
js 复制代码
new Promise(function (resolve) {
    console.log(this); // 严格模式下是undefined,非严格模式下是Window
    resolve();
});

new Promise((resolve) => {
    console.log(this); // Window
    resolve();
});
js 复制代码
const obj = {
    name: 'obj',
    test: function() {
        new Promise(function(resolve) {
            console.log(this);  // 严格模式下是undefined,非严格模式下是Window
            resolve();
        });

        new Promise((resolve) => {
            console.log(this);  // obj
            resolve();
        });
    }
};
obj.test();
js 复制代码
const example = () => {
    new Promise(function (resolve) {
      console.log(this); // 严格模式下是undefined,非严格模式下是Window
      resolve();
    });

    new Promise((resolve) => {
      console.log(this); // Window
      resolve();
    });
};

example();
  • this的优先级规则
    • 优先级从高到底
      • new 绑定
      • 显式绑定 (call, apply, bind)
      • 隐式绑定 (对象方法调用)
      • 默认绑定 (普通函数调用)
js 复制代码
function test() {
    console.log(this.name);
}

const obj = { name: 'obj' };

// 1. new 绑定
new test();  // test {}

// 2. 显式绑定
test.call(obj);  // 'obj'

// 3. 隐式绑定
obj.test = test;
obj.test();  // 'obj'

// 4. 默认绑定
test();  // undefined (严格模式) 或 Window (非严格模式)
  • 常见this指向问题及解决方案
js 复制代码
const obj = {
data: [1, 2, 3],
    process: function () {
      this.data.forEach(function (item) {
        console.log(this); // 严格模式undefined;非严格模式Window
      });
    },
};
obj.process();

//解决方案1
const obj = {
    data: [1, 2, 3],
    process: function() {
        this.data.forEach(item => {
            console.log(this);  // obj
        });
    }
};

//解决方案2
const obj = {
    data: [1, 2, 3],
    process: function() {
        this.data.forEach(function(item) {
            console.log(this);  // obj
        }.bind(this));
    }
};

//解决方案3
const obj = {
    data: [1, 2, 3],
    process: function() {
        const self = this;
        this.data.forEach(function(item) {
            console.log(self);  // obj
        });
    }
};
  • 特殊情况的this
js 复制代码
// 1. 链式调用
const calculator = {
    value: 0,
    add(num) {
        this.value += num;
        return this;  // 返回 this 实现链式调用
    },
    multiply(num) {
        this.value *= num;
        return this;
    }
};

calculator.add(5).multiply(2).add(3);  // value = 13

// 2. 工厂函数
function createPerson(name) {
    return {
        name,
        sayName() {
            console.log(this.name);
        }
    };
}

// 3. 类继承
class Animal {
    constructor(name) {
        this.name = name;
    }
    speak() {
        console.log(this.name + ' makes a noise.');
    }
}

class Dog extends Animal {
    speak() {
        super.speak();  // 调用父类方法
        console.log(this.name + ' barks.');
    }
}

记住 this 指向的关键点:

  1. 箭头函数没有自己的 this,继承自外层作用域
  1. 普通函数的 this 在调用时确定
  1. 严格模式会影响 this 的默认值
  1. 可以通过 call、apply、bind 改变 this 指向
  1. 对象方法中的 this 指向调用该方法的对象
  1. 构造函数中的 this 指向新创建的对象

上面每个打印都亲自真机打印的,说实话人麻了,太复杂了,这个记住关键点的情况下还得多练,否则碰到实际情况还是一脸懵

相关推荐
咖啡虫4 分钟前
css中的3d使用:深入理解 CSS Perspective 与 Transform-Style
前端·css·3d
拉不动的猪23 分钟前
设计模式之------策略模式
前端·javascript·面试
旭久24 分钟前
react+Tesseract.js实现前端拍照获取/选择文件等文字识别OCR
前端·javascript·react.js
独行soc34 分钟前
2025年常见渗透测试面试题-红队面试宝典下(题目+回答)
linux·运维·服务器·前端·面试·职场和发展·csrf
uhakadotcom1 小时前
Google Earth Engine 机器学习入门:基础知识与实用示例详解
前端·javascript·面试
麓殇⊙1 小时前
Vue--组件练习案例
前端·javascript·vue.js
outstanding木槿1 小时前
React中 点击事件写法 的注意(this、箭头函数)
前端·javascript·react.js
会点php的前端小渣渣1 小时前
vue的计算属性computed的原理和监听属性watch的原理(新)
前端·javascript·vue.js
_一条咸鱼_2 小时前
深入解析 Vue API 模块原理:从基础到源码的全方位探究(八)
前端·javascript·面试
患得患失9493 小时前
【前端】【难点】前端富文本开发的核心难点总结与思路优化
前端·富文本