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 指向新创建的对象

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

相关推荐
EndingCoder2 小时前
React从基础入门到高级实战:React 实战项目 - 项目三:实时聊天应用
前端·react.js·架构·前端框架
阿阳微客3 小时前
Steam 搬砖项目深度拆解:从抵触到真香的转型之路
前端·笔记·学习·游戏
德育处主任Pro4 小时前
『React』Fragment的用法及简写形式
前端·javascript·react.js
CodeBlossom4 小时前
javaweb -html -CSS
前端·javascript·html
打小就很皮...5 小时前
HBuilder 发行Android(apk包)全流程指南
前端·javascript·微信小程序
集成显卡6 小时前
PlayWright | 初识微软出品的 WEB 应用自动化测试框架
前端·chrome·测试工具·microsoft·自动化·edge浏览器
前端小趴菜056 小时前
React - 组件通信
前端·react.js·前端框架
Amy_cx7 小时前
在表单输入框按回车页面刷新的问题
前端·elementui
dancing9997 小时前
cocos3.X的oops框架oops-plugin-excel-to-json改进兼容多表单导出功能
前端·javascript·typescript·游戏程序
后海 0_o7 小时前
2025前端微服务 - 无界 的实战应用
前端·微服务·架构