热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

《YouDon'tKnowJS》浏览明白——this

1.this的降生假定我们有一个speak函数,经由历程this的运转机制,当运用差别的要领挪用它时,我们能够天真的输出差别的name。varme{name:me};functio

1. this的降生

假定我们有一个speak函数,经由历程this的运转机制,当运用差别的要领挪用它时,我们能够天真的输出差别的name。

var me = {name: "me"};
function speak() {
console.log(this.name);
}
speak.call(me) //me

然则假如没有this, 这时刻我们须要显现的通报上下文给该函数。这时刻必需硬性的指定上下文,代码的复杂度增添,天真性也短缺。

function speak(context) {
console.log(context.name);
}

2. this的运转机制

2.1 运转道理

When a function is invoked, an activation record, otherwise known as an execution context, is created. This record contains information about where the function was called from (the call-stack), how the function was invoked, what parameters were passed, etc. One of the properties of this record is the this reference which will be used for the duration of that function’s execution.

当函数被挪用时, 函数会建立一个activation object(实行上下文), 这个对象包含了函数在那里被挪用(挪用栈),函数的挪用体式格局,传入的参数,以及this值。

因而,我们能够看到,this值是在函数挪用时赋值的,而不是在声明的时刻。是动态的。

2.2 运转划定规矩

依据this的运作道理,我们能够看到,this的值和挪用栈(经由历程哪些函数的挪用运转到挪用当前函数的历程)以及怎样被挪用有关。

2.2.1 Default Binding(默许绑定)

当函数是被自力挪用时,this值在非严厉形式下为全局对象, 严厉形式下为undefined.

var a = 1;
function foo() {
var a = 2;
console.log(this.a);
}
function bar() {
debuuger;
foo();
}
bar();

翻开chrome devtool能够看到,在挪用foo时,函数的挪用栈为bar -> foo,挪用体式格局是自力挪用,且是在非严厉形式下,此时this值指向window,输出1。

《《You Don't Know JS》浏览明白——this》

2.2.2 Implicit Binding(隐式绑定)

var = 1;
function foo() {
debugger;
console.log(this.a);
}
var obj = {
a: 2,
foo: foo
}
obj.foo(); //2

此时,挪用foo时,函数前加上了对obj这个对象的援用,输出obj.a

因而,假如有上下文对象援用了函数,隐式绑定划定规矩会指定this值为该援用对象。

《《You Don't Know JS》浏览明白——this》

然则我们再看看下面这类状况。要注重的是,bar的值是对函数foo的援用,因而此时foo的挪用并没有上下文对象的援用,因而运用的是default binding, 输出1。要注重这类赋值的状况。

var a = 1;
function foo() {
debugger;
console.log(this.a);
}
var obj = {
a: 2,
foo: foo
}
var bar = obj.foo;
bar(); //1

2.2.3 Explicit Binding(显式绑定)

上面两种状况,要么this值为全局对象(非严厉形式),要么经由历程对象要领挪用,this指向挪用的对象。
那我想不经由历程对象挪用,而是自力挪用时又能指定this值为某个对象呢?这时刻,call,apply就降生了。它的第一个参数是this值,协助我们邃晓指定函数挪用时this的值。

var a = 1;
function foo() {
debugger;
console.log(this.a);
}
var obj = {
a: 2
}
foo.call(obj); //2

《《You Don't Know JS》浏览明白——this》

经由历程call, apply,我们能够在挪用时邃晓指定this值。另有一种状况是,有时刻我们愿望this值绑定在我们给定的对象上,而函数只须要吸收一些参数。特别是在第三方库中,它会供应一种要领,吸收要领须要的参数,然则不愿望你不测的修正了要领的this值,这时刻它可能会采纳bind这类硬性绑定的要领邃晓的指出this值。

在ES5中供应了Function.prototype.bind,它的运用场景就是协助你predicable的绑定this值。经常使用的运用场景为包裹函数、事宜绑定函数、setTimeout中绑定this

//包裹函数,用来吸收参数
function multiple(num) {
console.log(this.pen, num);
return this.pen * num;
}
var priceMapping = {
pen: 10
}
function calTotalPrices() {
return multiple.apply(priceMapping, arguments);
}
var total = calTotalPrices(3);
console.log(total); //30

//事宜绑定
var states = {
clickCount: 0
}
function clickHandler() {
this.clickCount++;
console.log(this.clickCount);
}
button.addEventListener('click', clickHandler.bind(states));

注重:当运用显现绑定时,假如第一个参数是null, undefined,则运用默许绑定划定规矩。为防止传入null, undefined时毛病的改变了全局值,最好建立一个空对象替代null, undefined

var ø = Object.create(null);
foo.call(ø);

2.2.4 new Binding(new绑定)

邃晓new的运作道理:

  1. 建立一个新对象;

  2. 对象链接到[[prototype]]上;

  3. this绑定到这个新对象上;

  4. 有显式的return,返回return,不然返回这个新对象。

2.2.5 优先级

new > 显现绑定(call,apply,bind) > 隐式绑定(要领挪用) > 默许绑定(自力函数挪用)

function foo(sth) {
this.b = sth;
console.log("a:", this.a, "b:", this.b);
}
var a = "window";
var obj1 = {
a: "obj1",
foo: foo,
}
var obj2 = {
a: "obj2",
foo: foo,
}
obj1.foo("obj1"); //a: obj1 b: obj1
obj1.foo.call(obj2, "obj2"); //a: obj2 b: obj2; 显现 > 隐式
var bar = foo.bind(obj1);
new bar("new"); //new > 显现

4. 箭头函数

箭头函数中的this并不适用于以上四种划定规矩。由于这里的this不是运用的传统this机制,而是运用的词法作用域,依据外层的作用域来决议this。运用机制不一样,该this也不能经由历程显现绑定来修正。

5. 总结

下一次再看到this的时刻,我们问本身两个题目:

  1. where to call: 函数的挪用位置是?

  2. how to call: 函数的挪用要领是?运用的划定规矩是?

  3. 运用划定规矩4条(按优先级排序):

    • new (新建立的对象)

    • 显式绑定 (绑定到指定对象,call, apply, bind:可展望的this);

    • 隐式绑定 (挪用的上下文对象,注重间接援用的毛病);

    • 默许绑定 (全局对象或undefined注重函数体是不是为严厉形式);


推荐阅读
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 本文讨论了编写可保护的代码的重要性,包括提高代码的可读性、可调试性和直观性。同时介绍了优化代码的方法,如代码格式化、解释函数和提炼函数等。还提到了一些常见的坏代码味道,如不规范的命名、重复代码、过长的函数和参数列表等。最后,介绍了如何处理数据泥团和进行函数重构,以提高代码质量和可维护性。 ... [详细]
  • 本文总结了Java中日期格式化的常用方法,并给出了示例代码。通过使用SimpleDateFormat类和jstl fmt标签库,可以实现日期的格式化和显示。在页面中添加相应的标签库引用后,可以使用不同的日期格式化样式来显示当前年份和月份。该文提供了详细的代码示例和说明。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • javascript  – 概述在Firefox上无法正常工作
    我试图提出一些自定义大纲,以达到一些Web可访问性建议.但我不能用Firefox制作.这就是它在Chrome上的外观:而那个图标实际上是一个锚点.在Firefox上,它只概述了整个 ... [详细]
  • 小程序wxs中的时间格式化以及格式化时间和date时间互转
    本文介绍了在小程序wxs中进行时间格式化操作的问题,并提供了解决方法。同时还介绍了格式化时间和date时间的互相转换的方法。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • JavaScript设计模式之策略模式(Strategy Pattern)的优势及应用
    本文介绍了JavaScript设计模式之策略模式(Strategy Pattern)的定义和优势,策略模式可以避免代码中的多重判断条件,体现了开放-封闭原则。同时,策略模式的应用可以使系统的算法重复利用,避免复制粘贴。然而,策略模式也会增加策略类的数量,违反最少知识原则,需要了解各种策略类才能更好地应用于业务中。本文还以员工年终奖的计算为例,说明了策略模式的应用场景和实现方式。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • 从零学Java(10)之方法详解,喷打野你真的没我6!
    本文介绍了从零学Java系列中的第10篇文章,详解了Java中的方法。同时讨论了打野过程中喷打野的影响,以及金色打野刀对经济的增加和线上队友经济的影响。指出喷打野会导致线上经济的消减和影响队伍的团结。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • 如何在HTML中获取鼠标的当前位置
    本文介绍了在HTML中获取鼠标当前位置的三种方法,分别是相对于屏幕的位置、相对于窗口的位置以及考虑了页面滚动因素的位置。通过这些方法可以准确获取鼠标的坐标信息。 ... [详细]
author-avatar
Json
技术QQ交流群:294088839.
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有