android 揭示动画

知道一种编程语言并不意味着您了解它或已正确使用它。 JavaScript也是如此。 尽管这是一种易于学习的语言,但对于新手,甚至对于经验丰富的程序员,都有很多陷阱。

使没有经验的开发人员感到困惑的一件事是this关键字的工作方式。 简而言之, this是一个引用别名-只是知道它确切引用了什么,这是棘手的部分。

本文旨在消除混淆,并深入了解this关键字的内部工作原理。

那么,什么是this无论如何?

简而言之, this是一个特殊的标识符关键字(在每个函数的范围内自动定义),指向正在执行的函数的“所有者”。 但是,要完全掌握其棘手的性质,我们需要回答两个关键问题:

this是如何创建的?

每次调用JavaScript函数时,都会创建一个新对象,其中包含有关传递了哪些参数,如何调用函数,从何处调用函数等信息。 该对象的主要属性之一是this引用, this引用自动绑定到函数是方法的对象。

注意:出于好奇, 在ECMAScript语言规范的第10.4.3节和链接的各节中对此进行了详细说明。

var car = {
  brand: "Nissan",
  getBrand: function(){
    console.log(this.brand);
  }
};

car.getBrand();
// output: Nissan

JS斌

在这个例子中this ,在使用this.brand ,是对基准car对象。 因此, this.brandcar.brand相同。

是什么this是指什么?

传递给所有函数的this值基于在运行时调用该函数的上下文 。 范围this是不关心功能如何以及在何处声明的,而是他们来自哪里(即上下文)调用。

每行JavaScript代码都在执行上下文中运行。 每次输入新的执行上下文时,都会重新定义this引用的对象,并保持固定状态,直到将其转移到其他上下文为止。 为了找到执行上下文(和this绑定),我们需要找到调用位置,即代码中调用函数的位置(而不是声明位置)。

让我们在以下示例中对此进行演示:

var brand = 'Nissan';
var myCar = {brand: 'Honda'};

var getBrand = function() {
  console.log(this.brand);
};

myCar.getBrand = getBrand;
myCar.getBrand();
// output: Honda

getBrand();
// output: Nissan

JS斌

即使myCar.getBrand()getBrand()指向一个相同的函数,但this函数的值却有所不同,因为它基于调用getBrand()的上下文。

众所周知,在函数内, this绑定到函数是方法的对象。 在第一个函数调用中,对象是myCar ,而在第二个函数调用中,对象是windowgetBrand()window.getBrand()相同)。 因此,不同的上下文会产生不同的结果。




调用上下文

现在,让我们看看是什么this点时,它的投入不同的上下文中来。

全球范围

所有JavaScript运行时都有一个称为全局对象的唯一对象 。 在浏览器中,全局对象是window对象。 在Node.js中,它称为global对象。

在全局执行上下文中(在任何函数之外), this是指全局对象,无论是否处于严格模式下。

当地范围

里面的功能,价值this取决于函数是如何被调用。 主要有三种变体:

this用在一个简单的函数调用

第一种变体是独立的函数调用,在此我们直接调用函数。

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

simpleCall();
// output: the Window object




动画公司人员架构 动画公司内部_java


<source type="image/webp"><source><img src="https://s2.51cto.com/images/blog/202312/24222703_65883fb75699410455.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=" alt="">



免费学习PHP!

全面介绍PHP和MySQL,从而实现服务器端编程的飞跃。

原价$ 11.95 您的完全免费


免费获得这本书


在这种情况下,值this不被调用设置。 由于代码不严格模式下运行,值this必须是一个对象,它默认为全局对象。

严格的模式 ,值this保持在任何它被设置在进入执行上下文时。 如果未定义,它将保持未定义状态,如下面的示例所示:

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

simpleCall();
// output: undefined
this用在对象的方法

我们可以将函数存储在对象的属性中,然后将其转换为可通过该对象调用的方法。 当将函数作为对象的方法调用时,其this值设置为调用该方法的对象。

var message = {
  content: "I'm a JavaScript Ninja!",
  showContent: function() {
    console.log(this.content);
  }
};

message.showContent();   // output: I'm a JavaScript Ninja!

JS斌

在这里, showContent()message对象的方法,因此this.content等于message.content

this用在构造函数

我们可以通过new运算符调用一个函数。 在这种情况下,函数将成为构造函数-对象的工厂。 与上面讨论的简单函数调用和方法调用不同,构造函数调用将一个全新的对象作为this的值传递,并隐式返回新对象作为其结果。

当函数用作构造函数(带有new关键字)时,其this值将绑定到新构造的对象。 如果我们错过了new关键字,那么这将是一个常规的功能, this将指向window对象。

function Message(content){
  this.content = content;
  this.showContent = function(){
    console.log(this.content);
  };
}

var message = new Message("I'm JavaScript Ninja!");

message.showContent();
// output: I'm JavaScript Ninja!

JS斌




在上面的示例中,我们有一个名为Message()的构造函数。 通过使用new运算符,我们创建了一个名为message全新对象。 我们还向构造函数传递了一个字符串,该字符串将其设置为新对象的content属性。 在代码的最后一行中,我们看到此字符串已成功输出,因为this指向新创建的对象,而不是构造函数本身。

如何this可以成功地操纵

在本节中,我们将研究一些用于控制this行为的内置机制。

在JavaScript中,所有函数都是对象,因此它们可以具有方法。 所有函数都具有的其中两个方法是apply()call() 。 我们可以使用这些方法将上下文更改为所需的内容,从而显式设置this的值。

apply()方法需要两个参数:一个目的是设置this到,和参数(可选的)阵列,以传递给该函数。

call()方法的工作原理与apply()完全相同,但是我们分别而不是在数组中传递参数。

让我们来看看它的作用:

function warrior(speed, strength){
  console.log(
    "Warrior: " + this.kind +
    ", weapon: " + this.weapon +
    ", speed: " + speed +
    ", strength: " + strength
  );
}

var warrior1 = {
  kind: "ninja",
  weapon: "shuriken"
};

var warrior2 = {
  kind: "samurai",
  weapon: "katana"
};

warrior.call(warrior1, 9, 5);
// output: Warrior: ninja, weapon: shuriken, speed: 9, strength: 5
warrior.apply(warrior2, [6, 10]);
// output: Warrior: samurai, weapon: katana, speed: 6, strength: 10

JS斌

在这里,我们有一个工厂函数warrior() ,该函数用于通过使用不同的warrior对象来创建不同类型的warrior。 因此,在该工厂函数中, this将指向我们使用call()和/或apply()传入的不同对象。

在第一个函数调用,我们使用call()方法来设置thiswarrior1对象,并传入我们需要的其他参数,以逗号分隔。 在第二个函数调用中,我们几乎执行相同的操作,但是这次我们传入warrior2对象,并将必要的参数放入数组中。

除了apply()call() ECMAScript 5还添加了bind()方法,该方法还允许我们设置在调用函数或方法时将哪个特定对象绑定到this对象。 让我们考虑以下示例:

function warrior(kind){
  console.log(
    "Warrior: " + kind +
    ". Favorite weapon: " + this.weapon +
    ". Main mission: " + this.mission
  );
}

var attributes = {
  weapon: "shuriken",
  mission: "espionage"
};

var ninja = warrior.bind(attributes, "ninja");

ninja();
// output: Warrior: ninja. Favorite weapon: shuriken. Main mission: espionage

JS斌

在此示例中, bind()方法的使用方式类似,但与call()apply()方法不同, warrior.bind()创建了一个新函数(与warrior()具有相同的主体和作用域),而不是修改原始的warrior()函数。 新功能的行为与旧功能相同,但其接收者绑定到attributes对象,而旧功能保持不变。

摘要

就是这样了。 这是您几乎需要了解的有关this关键字的所有内容,以便正确使用它并更有信心。 当然,在此过程中可能会遇到一些棘手的部分和一些常见问题。 这些将在以后的文章中进行探讨,请继续关注。

翻译自: https://www.sitepoint.com/inner-workings-javascripts-this-keyword/

android 揭示动画