javascript - 关于this在浏览器中的指向

查看:92
本文介绍了javascript - 关于this在浏览器中的指向的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="div0"></div>
</body>
<script>
  window.id = 'window';
  document.getElementById('div0').onclick = function(){
    alert(this.id);
    var callback = function(){
      alert(this.id)
    }
    callback();
  };
</script>
</html>

第一个输出"div0"可以理解很正常,为何第二个输出的是"window",callback是内部的函数他应该和外部的this都隐式调用指向div0,为何外部指向div0,内部指向window?
于是尝试命令行运行:

window.name = "window"
var text = function(){
  name = "text";
  alert(this.name);
  var callback = function(){
    alert(this.name)
  }
  callback()
}
text()

结果输出两次"text"
两者矛盾了吧,已晕望大神指点

解决方案

window.name = "window";
var text = function() {
    // name 没有用 var(或者 let、const)限定,是全局变量,即 window.name
    name = "text";

    // 参考下面 ①
    alert(this.name);

    var callback = function() {
        // 这个 this 参考 ②
        alert(this.name);
    };

    // ② 非对象方法方式调用,里面的 this 是全局对象,即 window
    callback();
};

// ① 非对象方法方式调用,text() 内部的 this 是全局对象,即 window
text();

所以自始至终你都是在操作同一个 name,即 window.name。如果想要理解 this,可以改一下代码

window.name= "window";

var obj = {
    text: function() {
        // 这两个 this 指的 obj,参考 ①
        this.name = "text";
        alert(this.name);

        // callback 内部的 this 参考 ②
        // 为了使用这里的 this,即 obj,可以用一个局部变量缓存
        var _this = this;
        var callback = function() {
            // 输出 widnow.name
            alert(this.name);

            // 输出 obj.name
            alert(_this.name);
        };

        // ② 对方法调用,callback() 内部的 this 是全局对象,即 window
        callback();
    }
};

// ① 方法调用,text 内部的 this 是 obj
obj.text();

// 这里的 obj.name 已经在 obj.text() 中赋值为 "text" 了
alert(obj.name);

补充一下

上面都是用的 es5 语法,如果用 es6 的箭头函数,或者说 Lambda 语法,就不需要缓存 _this

现在不是所有浏览器都支持 es6 语法,所以实际使用的过程中一般需要通过 babel 之类的工具编译成 es5。这里提出来只是顺着这个问题的知识点,多一个参考答案。

var obj = {
    text() {
        this.name = "text";
        var callback = () => {
            // Lambda 不改变作用域,这里的 this 就是 obj
            // this.name 就是 "text"
            alert(this.name);
        };
    }
};
obj.text();

这篇关于javascript - 关于this在浏览器中的指向的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆