深入理解javascript中的 “this”


Posted in Javascript onJanuary 17, 2017

一、前言:

我们知道 “this” 是javascript语言的一个关键字,在编写javascript代码的时候,经常会见到或者用到它。

但是,有一部分开发朋友,对 “this” 一知半解,下面我们就一起来探讨学习下javascript中 “this” 的具体含义吧!

二、This总结:

This指针作用域:

1)、在全局执行环境中使用this,表示Global对象,在浏览器中就是window对象。

2)、当在函数执行环境中使用this时,情况就有些复杂了。如果函数没有明显的作为非window对象的属性,而只是定义了函数,不管这个函数是不是定义在另一个函数中,这个函数中的this仍然表示window对象。如果函数显示地作为一个非window对象的属性,那么函数中的this就代表这个对象。

3)、当通过new运算符来调用函数时,函数被当做一个构造函数,this指向构造函数创建出来的对象。

三、各种情形下的DEMO:(当然,你也可以按照自己的想法来做各种测试...)

#在全局执行环境中使用this,表示Global对象,在浏览器中就是window对象

console.log(this); //Window
console.log(typeof this); //object
console.log(this === window); //true

##在函数执行环境中使用this时,如果函数没有明显的作为非window对象的属性,而只是定义了函数,不管这个函数是不是定义在另一个函数中,这个函数中的this仍然表示window对象

function A(){
 //在A函数中定义一个B函数
 function B(){
  console.log(this); //Window
  console.log(typeof this); //object
  console.log(this === window); //true
 }
 //在A函数内部调用B函数
 B();
}
//调用A函数
A();

###在函数执行环境中使用this时,如果函数显式地作为一个非window对象的属性,那么函数中的this就代表这个对象

//定义一个对象obj,并为她添加属性name,添加方法objFun
var obj = {
 name: '敲代码的怪蜀黍',
 objFun: function(){
  console.log(this); // Object {name: "敲代码的怪蜀黍"}
  console.log(typeof this); //object
  console.log(this === window); //false
  console.log(this.name); //敲代码的怪蜀黍
 }
}; 
//调用obj对象的方法
obj.objFun(); //this 绑定到当前对象,也就是obj对象

把上面的代码稍微改一下:

//定义一个对象obj,并为她添加属性name,添加方法objFun
var obj = {
 name: '敲代码的怪蜀黍',
 objFun: function(){
  console.log(this); //window
  console.log(typeof this); //object
  console.log(this === window); //true
  console.log('为了看效果而.'+this.name+'.已'); //为了看效果而..已
 }
};
var test = obj.objFun;
test();

这时候,你会神奇的发现,上面例子中的 this 又等于 window 了,到底是什么原因导致的呢?下面我们来分析分析:

我们首先要知道 “函数内部this的值不是静态的”,每次你调用一个函数它总是重新求值(但这一过程发生在函数代码实际执行之前),函数内部的this值实际上是由函数被调用的父作用域提供,更重要的是,她依赖实际函数的语法。

当函数被调用时,我们看紧邻括号“()”的左边。如果在括号的左侧存在一个引用,传递给调用函数的“this”值是引用所属于的那个对象,否则this的值就是全局对象。

我们再接着看看上面的例子,“var test = obj.objFun;” 这里表示没有调用函数,不用管。“test();”这里调用了函数,我们发现在括号“()”的左侧是一个变量test,test不是一个对象的引用,所以this的值就是全局对象。接下来,为了更深刻的理解上面的原理,我们来个更为复杂点的例子:

var name = 'window在手,天下我有!';
var obj = {
 name: '敲代码的怪蜀黍',
 objBar: {
  name: 'BOBO',
  barFun: function(){
   console.log(this.name);
  }
 }
};
//()左侧是barFun引用,它指向objBar对象,所以打印出 “BOBO”
var test1 = obj.objBar.barFun(); //BOBO
//()左侧是test2,test2它并不是某个对象的引用,所以打印出 “window在手,天下我有!”
var test2 = obj.objBar.barFun;
test2(); //window在手,天下我有!
//下面这个看起来复杂,其实抓住一点就行了:()左侧是testBar,testBar并不属于某个对象的引用,当然打印出来的还是 “window在手,天下我有!”
var test3 = obj.objBar;
var testBar = test3.barFun;
testBar(); //window在手,天下我有!

####当通过new运算符来调用函数时,函数被当做一个构造函数,this指向构造函数创建出来的对象

var name = 'window在手,天下我有!';
function A(){
 console.log(this.name);
}
A(); //window在手,天下我有! 
var objA = new A(); //undefined (因为objA并没有name属性)

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
Javascript-Mozilla和IE中的一个函数直接量的问题
Jan 09 Javascript
juqery 学习之五 文档处理 包裹、替换、删除、复制
Feb 11 Javascript
Javascript继承(上)——对象构建介绍
Nov 08 Javascript
动态加载dtree.js树treeview(示例代码)
Dec 17 Javascript
非常实用的js验证框架实现源码 附原理方法
Jun 08 Javascript
工作中比较实用的JavaScript验证和数据处理的干货(经典)
Aug 03 Javascript
简单理解js的冒泡排序
Dec 19 Javascript
使用vue.js写一个tab选项卡效果
Mar 25 Javascript
简单的Vue SSR的示例代码
Jan 12 Javascript
vue对storejs获取的数据进行处理时遇到的几种问题小结
Mar 20 Javascript
vue 扩展现有组件的操作
Aug 14 Javascript
javascript函数式编程基础
Sep 15 Javascript
JavaScript正则表达式exec/g实现多次循环用法示例
Jan 17 #Javascript
Javascript设计模式之装饰者模式详解篇
Jan 17 #Javascript
微信小程序图表插件(wx-charts)实例代码
Jan 17 #Javascript
jQuery图片拖动组件Dropzone用法示例
Jan 17 #Javascript
js生成随机数方法和实例
Jan 17 #Javascript
jQuery表单插件ajaxForm实例详解
Jan 17 #Javascript
js实现手机拍照上传功能
Jan 17 #Javascript
You might like
不错的一篇面向对象的PHP开发模式(简写版)
2007/03/15 PHP
linux下为php添加curl扩展的方法
2011/07/29 PHP
PHP遍历目录文件的常用方法小结
2017/02/03 PHP
ThinkPHP 3使用OSS的方法
2018/07/19 PHP
PHP使用glob方法遍历文件夹下所有文件的实例
2018/10/17 PHP
PDO::lastInsertId讲解
2019/01/29 PHP
自己动手制作jquery插件之自动添加删除行的实现
2011/10/13 Javascript
Area 区域实现post提交数据的js写法
2014/04/22 Javascript
处理文本部分内容的TextRange对象应用实例
2014/07/29 Javascript
JS获取及设置TextArea或input文本框选择文本位置的方法
2015/03/24 Javascript
安装使用Mongoose配合Node.js操作MongoDB的基础教程
2016/03/01 Javascript
详解js实现线段交点的三种算法
2016/08/09 Javascript
JavaScript队列、优先队列与循环队列
2016/11/14 Javascript
根据输入邮箱号跳转到相应登录地址的解决方法
2016/12/13 Javascript
浅谈vue-lazyload实现的详细过程
2017/08/22 Javascript
jQuery 改变P标签文本值方法
2018/02/24 jQuery
promise和co搭配生成器函数方式解决js代码异步流程的比较
2018/05/25 Javascript
JavaScript数组,JSON对象实现动态添加、修改、删除功能示例
2018/05/26 Javascript
JS浮点数运算结果不精确的Bug解决
2019/08/01 Javascript
vue 中几种传值方法(3种)
2019/11/12 Javascript
windows下wxPython开发环境安装与配置方法
2014/06/28 Python
使用Python中的tkinter模块作图的方法
2017/02/07 Python
Python使用add_subplot与subplot画子图操作示例
2018/06/01 Python
python实现指定字符串补全空格、前面填充0的方法
2018/11/16 Python
PyQt5实现简易计算器
2020/05/30 Python
python使用adbapi实现MySQL数据库的异步存储
2019/03/19 Python
python pandas时序处理相关功能详解
2019/07/03 Python
浅谈Django中view对数据库的调用方法
2019/07/18 Python
python将字符串转变成dict格式的实现
2019/11/18 Python
python 元组的使用方法
2020/06/09 Python
HTML5 DeviceOrientation实现手机网站摇一摇功能代码实例
2015/04/24 HTML / CSS
Nisbets法国:英国最大的厨房和餐饮设备供应商
2019/03/18 全球购物
工商管理本科毕业生求职信范文
2013/10/05 职场文书
关于读书的演讲稿500字
2014/08/27 职场文书
python如何读取.mtx文件
2021/04/22 Python
基于Redis zSet实现滑动窗口对短信进行防刷限流的问题
2022/02/12 Redis