在web项目中Javascript是一门必须要掌握的动态语言,基于Javascript的框架大多离不开不了最基础的Javascript的用法和原理。本文主要是总结一下Javascript中那万恶的this关键字。

开门见山,抛出一个观点:“Javascript中this永远是指向调用它的对象”。下面我会举3个最有代表性的例子来验证我的这个观点。

例一 对象方法调用

    var x = 1;
  function testThis(){
    console.log(this.x);
  } testThis(); // 这里声明了一个全局变量x,一个全局方法,这两个对象都绑定在Window上,所以当运行testThis()的结果就是取Window对象上的x成员,结果是1   var o={};
  o.x = 5;
  o.method = testThis; o.method(); // 此时,我们讲o对象的method指向了testThis, 当调用它的时候,this指向调用他的对象,这是x就是去o对象的x,结果是5

这个例子十分基础,也就是常见的对象调用方法的时候,方法里面的this就是指向调用他或者是拥有他的对象

例二 构造函数创建

    var x = 2;
  function test(){
    this.x = 1;
  }   var o = new test();
  console.log(o.x); // //这就是javascript中的构造函数,通过new来创建一个实例,这里取的值是绑定在对象o里面的x,所以是1 //下面这个例子是Angular中的Service,你可以直接理解成他会通过第二个参数new一个单例对象
app.service("MyService", function ($http, $modal) {
this.test = function() {
console.log(this);
test2();
} function test2() {
console.log(this)
}
} MyService.test() // 打印 MyService {test: function} 和 Window {} //这里log出来虽然test2()可以被test1()调用,但它其实并不属于Service, 所以如果test2里面调用this,就会出现常见的错误,哎呀妈呀,咋调不了自己的方法?!

这个例子我们项目中经常出现,而且很难解释清楚,就像还有人问我为什么controller中不直接使用this,而是要用$scope来绑定方法和变量,当然用this能够取代部分$scope,但是难免遇到this的上下文不同引起的一系列问题。这个问题的关键就是test2方法并不属于对象Service,但是由于在service闭包(closure)里面,他可以被Service调用,所以test2里面的this就不是指向Service,从而调用Service里面的其他方法就会报错。

例三 改变this指向

  function test(){
    console.log(this.x);
  }
  var o={};
  o.x = 1;
  o.m = test;   o.m.apply({x:5}); //
o.m.call() // undefined //通过apply/call来指定调用函数的this作用上下文,都是指用参数对象来调用o对象的函数,默认参数是Global

其实通过这个例子,大家就已经可以看到this的指向是不确定的,this值在进入上下文时确定,并且在上下文运行期间永久不变。上面的例子改变this的上下文,导致两次结果不一致也是最好的证据。

最后

本文最大的作用就是如果看完本文你能够理解this为什么有时候会跟自己期望不一样,而且能得到一个避免这样问题发生的解决方案,那我的目的就达到了。很幸运你能看到这里,解决方案呈现给大家:就像Angular要将属性和方法给你提供一个$scope来绑定属性,也像coffeeScript会在对象一开头有这么个赋值“ _this = this”,我们在自己的js实践中不妨定义"val self = this",在之后的作用域里面用self来操作对象的属性,这是解决之道。

玩转Javascript this用法的更多相关文章

  1. 玩下Javascript

    玩下Javascript 前言 好久没有更新博客了,也蛮少捣弄javascript,今儿看到一个题目,关于给你一个面板,你可以随意的在上面画矩形,可以移动和删除任意一个你创建的矩形,心血来潮搞着玩哈, ...

  2. javascript webstorm用法

    javascript  webstorm用法 一.什么是webstorm?       WebStorm 是jetbrains公司旗下一款JavaScript 开发工具.被广大中国JS开发者誉为“We ...

  3. JavaScript this用法总结(**************************************)

    JavaScript this用法总结 在JavaScript中,this关键字可以说是最复杂的机制之一.对this的作用机制缺乏比较深入的理解很容易在实际开发中出现问题. 1.this的作用 为什么 ...

  4. <a href="javascript:;">的用法说明

    <a href="javascript:;">的用法说明 1.标签的 href 属性用于指定超链接目标的 URL,href 属性的值可以是任何有效文档的相对或绝对 UR ...

  5. 玩转JavaScript module pattern精髓

    JavaScript module pattern是一种常见的javascript编码模式.这种模式本身很好理解,但是有很多高级用法还没有得到大家的注意.本文,我们将回顾这种设计模式,并且介绍一些高级 ...

  6. javascript:void(0)和javascript:;的用法

    一.JavaScript:void(0) 我们经常会使用到 javascript:void(0) 这样的代码,那么在 JavaScript 中 javascript:void(0) 代表的是什么意思呢 ...

  7. 弱弱的玩下Javascript

    前言 好久没有更新博客了,也蛮少捣弄javascript,今儿看到一个题目,关于给你一个面板,你可以随意的在上面画矩形,可以移动和删除任意一个你创建的矩形,心血来潮搞着玩哈,实现起来挺简单的,但这代码 ...

  8. JavaScript高级用法二之内置对象

    综述 本篇的主要内容来自慕课网,内置对象,主要内容如下 1 什么是对象 2 Date 日期对象 3 返回/设置年份方法 4 返回星期方法 5 返回/设置时间方法 6 String 字符串对象 7 返回 ...

  9. Javascript typeof 用法

    在js里用到数组,比如 多个名字相同的input, 若是动态生成的, 提交时就需要判断其是否是数组. if(document.mylist.length != "undefined" ...

随机推荐

  1. 关于Android中Fragment静态和动态加载的方法

    一.静态加载 1.首先创建一个layout布局fragment.xml,里面放要显示和操作的控件 2.创建一个layout布局main1.xml,用来实现页面的跳转(跳转为要实现静态加载的界面) 3. ...

  2. tomcat安装不成功.提示:failed to install tomcat6 service ,check your setting and permissions

    这个问题主要是因为旧版本卸载不完全导致的,可通过彻底删除旧版本解决,方案如下: 以管理员身份运行 命令提示符,弹出窗口 ,选择“是”,输入 sc delete tomcat5 ,或者 sc delet ...

  3. 【转】【Java/Android】Intent的简介以及属性的详解

    一.Intent的介绍 Intent的中文意思是“意图,意向”,在Android中提供了Intent机制来协助应用间的交互与通讯,Intent负责对应用中一次操作的动作.动作涉及数据.附加数据进行描述 ...

  4. BCM_SDK命令

    启动bcm的sdk,会进入一个类似shell的交互界面,在其中如入命令,可以配置交换机芯片.本文主要记录一下命令: 1.端口限速命令 2.链路聚合命令 3.i2c控制命令 启动方法: /tmp/bcm ...

  5. Spring Boot 官方文档学习(一)入门及使用

    个人说明:本文内容都是从为知笔记上复制过来的,样式难免走样,以后再修改吧.另外,本文可以看作官方文档的选择性的翻译(大部分),以及个人使用经验及问题. 其他说明:如果对Spring Boot没有概念, ...

  6. [转载]php设计模式之单例、多例设计模式

    单例(Singleton)模式和不常见的多例(Multiton)模式控制着应用程序中类的数量.如模式名称,单例只能实例化一次,只有一个对象,多例模式可以多次实例化. 基于Singleton的特性,我们 ...

  7. JAVA 多线程机制(一)

    PS:又开始忙叨JAVA了..前一阵子搞定了HTML+CSS,要开始写实验室的界面了,真没劲...博客到时候再更新吧! 先更新JAVA的吧... 多线程(一) 主要内容 1.JAVA中的线程 2.用T ...

  8. (转)x264重要结构体详细说明(1): x264_param_t

    结构体x264_param_t是x264中最重要的结构体之一,主要用于初始化编码器.以下给出了几乎每一个参数的含义,对这些参数的注释有的是参考了网上的资料,有的是自己的理解,还有的是对源代码的翻译,由 ...

  9. fastx tookit 操作fasta/fastq 文件 (1)

    准备测试文件 test.fq, 包含4条fastq 文件,碱基编码格式为phred64; @FC12044_91407_8_200_406_24 NTTAGCTCCCACCTTAAGATGTTTA + ...

  10. 【Graphlab】

    https://dato.com/ graphlab