Javascript的`this`===简单函数调用---考虑以下功能:函数foo(){console.log(“bar”);console.log(this);}foo();//调用函数请注意,我们在正常模式下运行,即不使用严格模式。在浏览器中运行时,“this”的值将记录为“window”。这是因为“window”是web浏览器范围内的全局变量。如果您在node.js等环境中运行这段代码,“this”将指应用程序中的全局变量。现在,如果我们通过添加语句“use strict”在函数声明的开头,“this”不再指任何一个环境中的全局变量。这样做是为了避免在严格模式下出现混淆`在本例中,这将只记录“未定义”,因为这就是它的含义,它没有定义。在以下情况下,我们将了解如何操作“this”的值。对对象调用函数---有不同的方法可以做到这一点。如果您在Javascript中调用了诸如“forEach”和“slice”之类的本机方法,那么您应该已经知道,在这种情况下,“this”变量指的是您调用该函数的“Object”(注意,在Javascript中,几乎所有东西都是“Object(对象)”,包括“Array(数组)”和“function(函数)”)。以下面的代码为例。var myObj={key:“Obj”};myObj.logThis=函数(){//我是一种方法console.log(this);}myObj.logThis();//myObj已被记录如果“Object”包含包含“Function”的属性,则该属性称为方法。调用此方法时,始终将其“This”变量设置为与其关联的“Object”。这对严格和非严格模式都适用。请注意,如果一个方法存储(或者说复制)在另一个变量中,那么对“this”的引用将不再保留在新变量中。例如://继续前面的代码片段var myVar=myObj.thisMethod;myVar();//根据操作模式记录窗口/全局/未定义考虑一个更常见的实际场景:var el=文档.getElementById('idOfEl');el.addEventListener('click',function(){console.log(this)});//addEventListener调用的函数将此作为元素的引用//所以点击元素就会记录该元素本身“new”关键字---考虑Javascript中的构造函数:职能人员(姓名){this.name=名称;this.sayHello=函数(){console.log(“Hello”,this);}}var awal=新人员(“awal”);awal.sayHello();//在`awal.sayHello`中,`this`包含对变量`awal的引用`这是如何工作的?好吧,让我们看看当我们使用“new”关键字时会发生什么。1.使用`new`关键字调用函数会立即初始化`Person`类型的`Object`。2.此“Object”的构造函数将其构造函数设置为“Person”。另外,请注意`typeof awal`只返回`Object`。3.这个新的“Object”将被指定为“Person.prototype”的原型。这意味着“Person”原型中的任何方法或属性都可用于“Person”的所有实例,包括“awal”。4.现在调用函数“Person”本身`这是对新构建对象awal的引用。挺直的,嗯?请注意,官方ECMAScript规范no-where规定此类函数是实际的“构造函数”函数。它们只是普通函数,“new”可以用于任何函数。只是我们这样使用它们,所以我们只把它们称为这样。在函数上调用函数:`call`和`apply`---所以是的,因为‘函数’也是‘对象’(实际上也是Javascript中的第一类变量),所以即使函数也有。。。好吧,它们自己的功能。所有函数都继承自全局“Function”,其许多方法中有两个是“call”和“apply”,这两个方法都可以用于在调用它们的函数中操作“this”的值。函数foo(){console.log(this,arguments);}var thisArg={myObj:“很酷”};foo.call(thisArg,1,2,3);这是使用“call”的典型示例。它基本上接受第一个参数,并将函数“foo”中的“this”设置为对“thisArg”的引用。传递给“call”的所有其他参数都作为参数传递给函数“foo”。因此,上面的代码将在控制台中记录`{myObj:“is cool”},[1,2,3]`。在任何函数中更改“this”值的非常好的方法。`apply’与call’accept几乎相同,它只需要两个参数:thisArg和一个包含要传递给函数的参数的数组。因此,上述“call”调用可以转换为“apply”,如下所示:foo.apply(thisArg,[1,2,3])注意,“call”和“apply”可以通过我们在第二个项目符号中讨论的点方法调用覆盖“this”的值。足够简单:)正在演示`绑定`!---`bind`是call`和apply的兄弟。它也是所有函数从Javascript中的全局“Function”构造函数继承的方法。“bind”和“call”/“apply”的区别在于,“call(调用)”和“apply(应用)”实际上都会调用函数`另一方面,bind`返回一个预先设置了`thisArg`和`arguments`的新函数。让我们举一个例子来更好地理解这一点:函数foo(a,b){console.log(this,参数);}var thisArg={myObj:“现在更酷了”};var绑定=foo.bind(thisArg,1,2);console.log(绑定类型);//日志`函数`console.log(绑定);/*日志`函数(){本机代码}`*/bound();//调用`.bind返回的函数`//logs`{myObj:“现在更酷了”},[1,2]`看到三者之间的区别了吗?这是微妙的,但它们的用法不同。与“call”和“apply”类似,“bind”也会覆盖由点方法调用设置的“this”的值。还要注意,这三个函数都不会对原始函数进行任何更改`call`和`apply`将从新构建的函数中返回值,而`bind`将返回新构造的函数本身,以便调用。额外的东西,复制这个---有时,您不喜欢“this”随范围(特别是嵌套范围)的变化而变化。看看下面的例子。var myObj={您好:函数(){返回“世界”},myMethod:函数(){//复制这个,变量名是区分大小写的var that=这个;//回调ftw\o/foo.bar(“args”,函数(){//我想在这里打“你好”this.hello();//错误//但‘这’指的是‘foo’该死!//哦,等等,我们有备份/this.hello();//“世界”});}};在上面的代码中,我们看到`this`的值随嵌套范围而改变,但我们希望从原始范围中获得`this'的值。所以我们把这个复制到那个,用拷贝代替这个。聪明,嗯?索引:1.默认情况下“this”中包含什么?2.如果我们使用Object-dot符号将函数作为方法调用会怎么样?3.如果我们使用“new”关键字怎么办?4.如何使用“call”和“apply”操作“this”?5.使用“bind”。6.复制“this”以解决嵌套范围问题。