IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> this指向问题 -> 正文阅读

[JavaScript知识库]this指向问题

this的指向

全局作用域中的this

指向它本身

函数中的this

函数中this的指向,实在函数被调用的时候确定的

函数被调用时,会产生一个执行上下文,执行上下文被创建的时候会做几件事情:创建变量对象;确定作用域链,确定this指向

在函数执行过程中,this一旦被确定,就不可更改了

      var name = "kaka";
      var obj = { name: "lulu" };
      function test1() {
        this=obj  // 报错 Uncaught SyntaxError: Invalid left-hand side in assignment
        console.log(this.name);
      }
      test1();

普通函数

如果调用者函数,被某一个对象所拥有(作为对象的方法),那么该函数在调用时,内部的this指向该对象(函数的调用者)。如果函数独立调用,那么该函数内部的this指向undefined;再非严格模式下,当this指向undefined和null时,会被默认指向全局对象

      var a = 20;
      var obj = {
        a: 10,
        c: this.a + 20,
        fn: function () {
          // "use strict";
          return this.a;
        },
      };
      console.log(obj.c);
      console.log(obj.fn());
      var func = obj.fn;
      console.log(func());
      console.log(window.func());

在非严格模式下输出结果是:40 10 20 20

在严格模式下输出结果是:40 20 报错:undefined没有a属性 20(由于前面报错没有打印)

obj虽然有{},但是他并没有产生一个独立上下文,没有产生一个函数作用域,所以this指向是全局对象

构造函数

构造函数中的this指向实例对象

      function Person(name, age) {
        this.name = name;
        this.age = age;
        console.log(this);   // {name:"潘周聃",age:29}
      }
      var p = new Person("潘周聃", 29);

箭头函数

箭头函数没有自己的this,this始终沿着作用域链向上找,它实在函数定义是确定的,而不是执行时,也就是箭头函数所在的执行上下文创建的时候,确定了箭头函数中this的指向

箭头函数中的this会保留在定义该函数时的上下文

King被调用的时候产生了一个上下文,箭头函数定义是在这个上下文中;所以这里的this指向实例对象

      var name = "潘周聃,";
      var content = "男,29岁";
      function King(name, content) {
        this.name = name;
        this.content = content;
        setTimeout(() => {
          console.log(this.name + this.content);  // 欧豪,", "你是我的神"
        }, 0);
      }
      const k = new King("欧豪,", "你是我的神");

如果我们使用普通函数,this指向全局对象

      var name = "潘周聃,";
      var content = "男,29岁";
      function King(name, content) {
        this.name = name;
        this.content = content;
        setTimeout(function () {
          console.log(this.name + this.content);  // 潘周聃,男,29岁
        }, 0);
      }
      const k = new King("欧豪,", "你是我的神");

再来一个例子

    <div class="good">这是一个div</div>

      const dom = document.getElementsByClassName("good")[0];
      dom.addEventListener("click", () => {
        console.log(this, "箭头函数");   // this指向全局对象Window
      });
      dom.addEventListener("click", function () {
        console.log(this, "普通函数");  // this指向dom,函数的调用者
      });

修改函数的this指向

call

fn.call(targetObj,param1,param2……)

      var name = "kaka";
      var obj = { name: "lulu" };
      function test1() {
        console.log(this.name);
      }
      test1.call(obj);  // 控制台输出"lulu"

会自动执行一次函数,改变函数中的this指向;

参数以参数序列的形式传递,第一个参数是this要指向的对象,后面是函数的参数

      var name = "kaka";
      var obj = { name: "lulu" };
      function test1(num1, num2) {
        console.log(this.name);    // lulu
        console.log(num1 - num2);  // 8
      }
      test1.call(obj, 10, 2);

apply

fn.apply(targetObj,[params])

?      var name = "kaka";
?      var obj = { name: "lulu" };
?      function test1(num1, num2) {
?        console.log(this.name);   // lulu
?        console.log(num1 - num2);  // 8
?      }
?      test1.apply(obj, [10, 2]);

会自动执行一次函数,改变函数中的this指向

和bind一样,只是传递给函数的参数不一样,apply以数组的形式传参

bind

bind返回的是函数

// 这是错误的写法
      var name = "kaka";
      var obj = { name: "lulu" };
      function test1(num1, num2) {
        console.log(this.name);  // kaka
        console.log(num1 - num2);  // NaN
      }
      test1.bind(obj, 10, 2);
      test1();

因为test1函数中的this是在函数被调用的时候确定的,bind会返回一个函数,但是并没有调用函数;函数真正被调用的时候this指向undefined,非严格模式下指向全局对象,所以是打印kaka

bind不会自动调用一次函数,其他和call一样的

// 正确方式
      var name = "kaka";
      var obj = { name: "lulu" };
      function test1(num1, num2) {
        console.log(this.name);    // lulu
        console.log(num1 - num2);  // 8
      }
      const bindFn = test1.bind(obj, 10, 2);
      bindFn();  // 或者test1.bind(obj, 10, 2)();
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-30 08:37:40  更:2022-04-30 08:37:53 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 1:21:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码