资讯专栏INFORMATION COLUMN

Javascript中this基础应用

NicolasHe / 563人阅读

摘要:不过,匿名函数的执行环境具有全局性,因此其对象通常指向。示例如下依然指向全局全局方法指向匿名函数目前为止,一切都符合预期表现。指向指向全局调用对象方法调用方法内部方法虽然有点绕,但是还是可以明白的,指向调用方法该对象,匿名函数指向全局。

前言

以下内容只针对非严格模式,严格模式区不说了
如果看过《JavaScript高级程序设计(第3版)》的人都应该有印象,里面关于this对象是这么形容的

this 对象是在运行时基于函数的执行环境绑定的:在全局函数中,this等于window,而当函数被作为某个对象的方法调用时,this 等于那个对象。不过,匿名函数的执行环境具有全局性,因此其 this 对象通常指向 window。
demo1

示例如下

var a = 10,
  obj = {
    a: 20
  };

function log() {
  var a = 30;
  console.log(this.a); //依然指向全局
};

console.log(this.a); // 全局
log(); //方法
log.call(obj); //指向obj

;
(function () {
  console.log(this.a) //匿名函数
})()

// 10
// 10
// 20
// 10

目前为止,一切都符合预期表现。然后我们再看些复杂点的写法。

demo2
var a = 10,
  obj = {
    a: 20,
    log: function () {
      console.log(this.a); //指向obj
    }
  };

function log() {
  function _log() {
    console.log(this.a); //指向全局
  };
  _log();
};

obj.log(); //调用对象方法
log(); //调用方法内部方法

// 20
// 10

虽然有点绕,但是还是可以明白的,this指向调用方法该对象,匿名函数this指向全局
看到这里我们好像已经大概明白this是怎么一回事了,然后我们再写复杂点

demo3
var a = 10,
  obj = {
    a: 20,
    b: this.a + 30
  };
console.log(obj.b); // 40

是不是又猛的怀疑人生了?明明应该this是指向obj得出50,为什么会指向全局得出40的!?
想想上面说的当函数被作为某个对象的方法调用时, this 等于那个对象。难道属性值又是另一回事?
带着疑问我们直接打印出this看看

var a = 10,
  obj = {
    a: 20,
    b: this
  };
console.log(obj.b === window); //true

所以属性值里的this真的指向全局,于是我们可以假设得出一个结论:当函数被作为某个对象的方法调用时, this 等于那个对象,而某个对象的属性值的this是直接指向全局的
听起来好拗口,是不是意思对象的方法this指向对象,属性值指向全局!?

demo4

带着疑问我们直接看例子

var a = 10,
  obj = {
    a: 20,
    log: function () {
      console.log(this.a);
    }
  };
var fn = obj.log;
fn(); //调用赋值方法10

正如前面所说,当函数被作为某个对象的方法调用时, this 等于那个对象。如果不是该对象直接调用时,this指向调用对象。
基于这个结论,即使中间经过几层函数调用也一样的

var a = 10,
  obj = {
    a: 20,
    log: function () {
      console.log(this.a); //指向obj
    }
  };

function all_log(fn) {
  fn();
}

all_log(obj.log); // 10

看到了吧,即使经过一个中间函数调用,实际相当于window调用对象方法,所以this也是指向全局的.

demo5

然后看看经常会用到的函数return出的this指向

var a = 10,
  obj = {
    a: 20,
    log: function () {
      return function () {
        console.log(this.a); //指向??
      }
    }
  };
obj.log()(); //10

衹要基础稍好也能理解,因为obj.log()返回一个匿名函数,然后相当于在全局下再调用匿名函数,因此this直接指向全局了。书里官方点的解释就是

每个函数在被调用时都会自动取得两个特殊变量: thisarguments。内部函数在搜索这两个变量时,只会搜索到其活动对象为止,因此永远不可能直接访问外部函数中的这两个变量(例子是指obj)

需要注意的是如果没有明确指向全局的话this实际上都是指向undefined的,衹是非严格模式下,它会被自动指向全局对象。

function log() {
  "use strict";
  console.log(this === window);
}

log(); // 独立调用false
window.log(); // window下调用 true
demo6

书里还提到一个挺有意思的写法

var a = 10,
  obj = {
    a: 20,
    log: function () {
      console.log(this.a); //指向??
    }
  };
(obj.log = obj.log)(); //先赋值再调用 10

你会发现居然this也指向全局了。
因为代码先执行了一条赋值语句,然后再调用赋值后的结果。因为这个赋值表达式的值是函数本身,所以 this 的值不能得到维持,结果就返回了10。

demo7

如果是作为构造函数使用的情况下

function Person() {
  this.name = "mike";
  this.log = function () {
    console.log(this);
  }
};

var man = new Person();
man.log();//Person {name: "mike", log: function}

里面的this是指向new出来的对象,详情可以看看我之前写的博文关于Javascript中的new运算符,构造函数与原型链一些理解

demo8

还有种情况是通过callapply修改this指向,它会强制指向方法的第一个参数

var a = 10,
  obj = {
    a: 20
  };

function log() {
  console.log(this.a);
};

log.call(obj); //指向obj
log.apply(obj); //指向obj
基于上面的情况,我们可以得出几个结论

1, this 对象是在运行时基于函数的执行环境绑定的
2, 如果没有明确指向全局的话this实际上都是指向undefined的,衹是非严格模式下,它会被自动指向全局对象
3, 当函数被作为某个对象的方法调用时,this 等于那个对象
4, 当某个对象的属性值里的this是直接指向全局对象
5, 匿名函数的执行环境具有全局性,因此其 this 对象通常指向全局对象
6, 构造函数中的this会指向它实例化对象
7, call或apply方法能强制修改this指向方法指定对象

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/106222.html

相关文章

  • 学习React之前你需要知道的的JavaScript基础知识

    摘要:和类在开始时遇到类组件,只是需要有关类的基础。毕竟,中的条件呈现仅再次显示大多数是而不是特定的任何内容。 在我的研讨会期间,更多的材料是关于JavaScript而不是React。其中大部分归结为JavaScript ES6以及功能和语法,但也包括三元运算符,语言中的简写版本,此对象,JavaScript内置函数(map,reduce,filter)或更常识性的概念,如:可组合性,可重用...

    bitkylin 评论0 收藏0
  • JavaScript基础心法——call apply bind

    摘要:原文地址基础心法欢迎。也就是说,这三个方法可以改变函数体内部的指向。令为一个空列表。提供作为值并以作为参数列表,调用的内部方法,返回结果。在外面传入的值会修改并成为值。语法其中,就是指向,是指定的参数。 原文地址:JavaScript基础心法——call apply bind 欢迎star。 如果有错误的地方欢迎指正。 整理call、apply、bind这三个方法的的知识点。 之前...

    techstay 评论0 收藏0
  • [译] 在你学习 React 之前必备的 JavaScript 基础

    摘要:前言在理想的状态下,你可以在深入了解之前了解和开发的所有知识。继承另一个类的类,通常称为类或类,而正在扩展的类称为类或类。这种类型的组件称为无状态功能组件。在你有足够的信心构建用户界面之后,最好学习。 原文地址:JavaScript Basics Before You Learn React 原文作者: Nathan Sebhastian 写在前面 为了不浪费大家的宝贵时间,在开...

    Chaz 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<