this的用法 – JavaScript深入浅出(二)
写在前面
上一篇中,我们对于JavaScript中原始值、复杂值以及内存空间进行了一个深入浅出的总结,这次我们来聊一聊JavaScript中this关键字的深入浅出的用法.
在 JavaScript 中,this 是动态绑定,或称为运行期绑定的,这就导致 JavaScript 中的 this 关键字有能力具备多重含义,带来灵活性的同时,也为初学者带来不少困惑。希望这篇文章可以解决初学者心中what’s this ?的困惑。
创建函数时,系统会在默认创建一个名为this的关键字,这也就是说this,只能在函数内部使用;从根本上说,由于运期绑定的特性,JavaScript中this的关键字要丰富的多,这完全取决于函数调用的方式:
1)作为函数调用
2)作为对象方法调用
3)使用call,apply调用
4)作为构造函数调用
我没有按这四种调用方式依次来介绍,但是在例子中都有体现。

1、如何确定this值?
我们来看一个例子:1)当从全局域中调用sayFoo函数时,this指向window对象;2)当它作为myObject的一种方法被调用时,this引用myObject;
通过上面的例子,我们发现this 是基于调用函数的上下文的,考虑一下myObject.sayFoo和sayFoo都指向了相同的函数,然而,调用sayFoo的方式不同,this的值也不同。
通过这个例子,我们也可以体会到了a、作为函数调用;b、作为对象的方法调用时,this的不同指向
2、在嵌套函数中用this关键字
当在嵌套函数内部使用this时,会发生什么事呢?通过下面的例子,我们明显看出嵌套函数内部的this都失去方向,都指向了window对象

我们在来看一种情况(原理是一样的),我们把一个匿名函数作为参数传递给一个对象的方法中:,当匿名函数在foo.func1(函数内的函数)内部被调用时,匿名函数的this值同样是window对象的引用.

3、充分利用作用域链研究嵌套函数的问题
JavaScript的程序员的力量是强大的,为了解决在嵌套函数内部this指向的问题,他们想出了变量代替的方法,可以简单的在父函数使用作用域链来保留对this的引用,以便this不丢失。约定俗成,我们一般把变量定义为that
我们来看一个例子:

这样,我们就很好的解决了嵌套函数内部this指向的问题
4、使用call()或apply()控制this值
我们可以通过apply()或call()来重写/控制this值,以便定义调用函数时this指向哪个对象。“嘿,告诉x函数,调用的时候把z对象作为this值使用”,这样做我们就可以改变JavaScript中决定this值的方式(取代默认模式)

上述代码使用了call(),但也可以使用apply()。两者区别在于为函数传递参数的方式不同:a、使用call(),参数只是使用逗号分隔的值;b、如果使用apply(),参数值在数组内传递。
下面使用apply可以达到同样的效果

5、在用户自定义构造函数内部使用this 关键字
在构造函数中,this默认值的变化与使用call或apply时this默认值变化不同,使用new关键词调用函数时,在构造函数中声明的this引用实例本身

在使用new关键词调用构造函数时,this引用’即将创建的对象’。如果不使用new关键词,this值将是调用Person的上下文 – 上例中是window对象

写在后面
this在不同调用方式下的含义 只是JavaScript中一个很小的概念,但是也是我们借此可以深入理解JavaScript函数的执行环境,更进一步帮组我们了解闭包等其他概念,掌握了这些概念,才能充分发挥JavaScript的特点,才会发挥JavaScript语言特性的强大之处。

this的用法 – JavaScript深入浅出(二)的更多相关文章
- 函数原型属性-JavaScript深入浅出(三)
前两次总结了JavaScript中的基本数据类型(值类型<引用类型>,引用类型<复杂值>)以及他们在内存中的存储,对内存空间有了一个简单的了解,以及第二次总结了this深入浅出 ...
- 原型那些事 - JavaScript深入浅出(三)
前两次总结了JavaScript中的基本数据类型(值类型<引用类型>,引用类型<复杂值>)以及他们在内存中的存储,对内存空间有了一个简单的了解,以及第二次总结了this深入浅出 ...
- 从头开始学JavaScript (十二)——Array类型
原文:从头开始学JavaScript (十二)--Array类型 一.数组的创建 注:ECMAscript数组的每一项都可以保存任何类型的数据 1.1Array构造函数 var colors = ne ...
- 学习javascript数据结构(二)——链表
前言 人生总是直向前行走,从不留下什么. 原文地址:学习javascript数据结构(二)--链表 博主博客地址:Damonare的个人博客 正文 链表简介 上一篇博客-学习javascript数据结 ...
- JavaScript深入浅出6-函数和作用域
慕课网教程视频地址:Javascript深入浅出 函数的概念:定义一次可调用多次的javascript代码段 创建函数:声明 function fuc(){} 声明前置 表达式 var fuc= ...
- JavaScript深入浅出5-数组
慕课网教程视频地址:Javascript深入浅出 数组:值的有序集合 创建数组:字面量,构造器new array() 数组的读写:push() 尾部加入新元素 unshift() 头部加入新元素 po ...
- 初探JavaScript(二)——JS如何动态操控HTML
除去五一三天,我已经和<JavaScript Dom编程艺术>磨合了六天,第一印象很好.慢慢的,我发现这是一块排骨,除了肉还有骨头.遇到不解的地方就会多看几遍,实在不懂的先跳过,毕竟,初次 ...
- JavaScript深入浅出4-对象
慕课网教程视频地址:Javascript深入浅出 对象的结构:包含一系列无序的属性,每个属性都有字符串key和对应的值 创建对象:对象字面量.new/原型链.Object.create 对象的属性操作 ...
- JavaScript深入浅出3-语句
慕课网教程视频地址:Javascript深入浅出 程序由语句组成,语句遵守特定语法规则 块 block {} 没有块级作用域 声明 var 异常 try catch finally 函 ...
随机推荐
- nopCommerce 3.9 大波浪系列 之 可退款的支付宝插件(下)
一.回顾 支付宝插件源码下载地址:点击下载 上篇介绍了使用支付宝插件进行支付,全额退款,部分退款还有插件的多店铺配置,本文介绍下如何实现的. 二.前期准备 插件主要有3个功能: 多店铺插件配置 支付功 ...
- 表达式求值(二叉树方法/C++语言描述)(二)
表达式二叉树节点的数据可能是运算数或运算符,可以使用一个联合体进行存储:同时还需要一个变量来指示存储的是运算数还是运算符,可以采用和栈方法求值中一样的枚举类型TokenType: typedef en ...
- ffmpeg编解码视频导致噪声增大的一种解决方法
一.前言 ffmpeg在视音频编解码领域算是一个比较成熟的解决方案了.公司的一款视频编辑软件正是基于ffmpeg做了二次封装,并在此基础上进行音视频的编解码处理.然而,在观察编码后的视频质量时,发现图 ...
- Web如何应对流量劫持?
虽然互联网经过多年的发展,可是网站使用的底层协议仍是 HTTP,HTTP 作为一种明文传播协议,所有的传输数据都是明文,我们都知道在通信中使用明文(不加密) 内容可能会被窃听,同时网站存在被劫持的风险 ...
- 【我的漫漫跨考路】数据结构之单链表线性存储实现 Beta
正文之前 昨天晚上阶段性的完成了一部分数学的复习,所以今天打算撸一撸代码,然后发现提电脑忘指针.所以自己磕磕盼盼,对照了一下网上的代码,总算把线性存储单链表的数据类型实现,给自己写出来了. 废话不多说 ...
- MongoDB安全策略
一,修改启动端口 mongo的默认端口为27017 如果启用的是27017端口并且在公网上很容易被人攻击,所以第一点我们要修改端口 sudo ./mongod --dbpath=/data/db -- ...
- [NOIP2011] 聪明的质监员 二分+前缀和
考试的时候打的二分但没有用前缀和维护.但是有个小细节手误打错了结果挂掉了. 绝对值的话可能会想到三分,但是注意到w增大的时候y是减小的,所以单调性很明显,用二分就可以.但注意一个问题,就是二分最后的结 ...
- Java第一个程序(CMD环境)
在新学Java配置好JDK之后,根据例子用CMD命令运行第一个java程序出错.是这样的: 1,在某一个盘(最好是英文路径),新建记事本输入java程序,例如: 保存为HelloJava.java. ...
- HDU 5067 Harry And Dig Machine:TSP(旅行商)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5067 题意: 给你一个n*m的地图,地图上标着对应位置的石子数.你从左上角出发,每次可以向上下左右四个 ...
- Kettle安装和配置
0x01 Kettle软件概览 Spoon:集成开发环境 Kitchen:作业的命令行运行程序,可以通过Schell脚本来调用 Pan:转换的命令行程序 Carte:轻量级的HTTP服务,后台运行,监 ...