this是面向对象语言中的一个重要概念,在JAVA,C#等大型语言中,this固定指向运行时的当前对象。但是在JS中,由于 javascript的动态性(解释执行,当然也有简单的预编译过程),this的指向在运行时才确定。这个特性让我们有时会给乱了方向,如果掌握了它的工作原理,那么它给我们带来了编程上的 自由和灵活,结合apply(call)方法,可以使JS变得异常强大。

默认的this:
Javascript 下,所有的属性都默认为window对象所有,所以说this也不例外,看下面的例子,先来个热身:

 var txt = “Hello,Alex!”;
function demo(){
var txt = “Hi,Alex!”;
alert(this.txt);//与window.txt相同
}
demo();//output Hello,Alex!

由此可见,demo()执行时,函数里的this 指向全局对象window。接下来,我们换一种方式,以类的方式来调用一下demo,看看this把方向指向何方

 var AA = new demo();
AA();//output undefined

当demo被实例化后,this就指向了当前实例化的对象,所以在demo这个类里虽然有个txt变量,这里txt属于类demo的局部变量,而没有定义指针引用,所以,demo被实例化后,this根本没指向局部变量txt,所以引用txt,会被告知未定义(undefined)。

接下来,我们来看看,绑定事件的this又指向何方:
html:

 <input  id=”demo” style=”width:200px; height:50px ;background:#000″ type=”button” value=”demo” />

Javascript:

 function showMsg(){
alert(this.style.width);
}
window.onload = function(){
document.getElementById(“demo”).onclick = showMsg;
}

当div被点击: alert(this.style.width) 输出是 200px,可见当前this为onclick引用的对象(document.getElementById(“demo”))

换一下方式,看看this又指向谁?

 window.onload = function(){
document.getElementById(“demo”).onclick = function(){showMsg()};
}

这里,当div被点击 alert(this.style.width) 脚本报错this.style.width为空或不是对象,原因:当前this指向function(){}匿名函数,这匿名函数里不存在style.width属性,所以脚本报错。

顺着上面绑定事件的this,说说YUI里的on方式绑定的this指向:

 YUI({combine: true}).use(‘io’, ‘until’, function (Y) {
var Demo = {
init : function(){
Y.one(“#demo”).on(“click”,this.showMsg)
},
demo_txt : “hello,tid!”,
showMsg : function(){
alert(this.demo_txt);
}
}
});
Demo.init();

当input 被点击的时候, showMsg是有被执行,可是this.demo_txt 输出的却是undefined,而不是hello,tid!。因为这里的this已不再指向Demo对象,而是指向on绑定的函数的对象了,所以绑定的对象里不存在demo_txt属性。
如果想得到输出为“hello,tid!”,我们得换别一种方式去调用:

 init : function(){
var $this = this;
Y.one(“#demo”).on(“click”,function(){$this.showMsg()})
}

这样,showMsg的this就指向了Demo对象,这情况,就像我们平时使用AJAX发出请求,请求成功后回调方法里的this一样,在这里就不展开说明了。

apply/call函数里的this:
先简单介绍apply/call这两个方法:
call, apply作用就是借用别人的方法来调用,就像调用自己的一样.从而改变了当前this的指向.
call(this, args1, args2, args3,…)  //参数为个数
apply(this, [args1, args2, args3,…])//参数为数组

下面来看几个简单的例子:

 function sayMsg(word1,word2){
alert(word1 + word2);
}
function sayMsgToo(word1,word2){
sayMsg.call(this,word1,word2);
//sayMsg.apply(this,[word1,word2]);
//sayMsg.apply(this,arguments);
}
sayMsgToo(“Hi”,”,Alex!”); //output Hi,Alex!

上述只简单介绍apply/call两方法的调用与区别,下面,我们看看这两个方法如何改变this指向(this引用的传递)

 function sayMsg(){
alert(this.word1 + this.word2);
}
function sayMsgToo(word1,word2){
this.word1 = word1;
this.word2 = word2;
sayMsg.call(this);
//sayMsg.apply(this);
}
sayMsgToo(“Hi”,”,tid!”) //output Hi,tid!

这里可以看出来sayMsg里的this指向了sayMsgToo,这种方式的运用,可以用于模拟继承,从而实现了代码的重用。

this,小心!的更多相关文章

  1. 如何一步一步用DDD设计一个电商网站(九)—— 小心陷入值对象持久化的坑

    阅读目录 前言 场景1的思考 场景2的思考 避坑方式 实践 结语 一.前言 在上一篇中(如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成),有一行注释的代码: public interfa ...

  2. Qt 中使用Singleton模式需小心

    在qt中,使用Singleton模式时一定要小心.因为Singleton模式中使用的是静态对象,静态对象是直到程序结束才被释放的,然而,一旦把该静态对象纳入了Qt的父子对象体系,就会导致不明确的行为. ...

  3. “如何稀释scroll事件”的思考(不小心写了个异步do...while)

    看了下园友的一帖子:http://www.cnblogs.com/xzhang/p/4145697.html#commentform 本来以为是很简单的问题,但仔细想想还挺有意思的.简单的说就是增加事 ...

  4. linux中不小心将rpm命令卸载了,怎么恢复?

    今天在搭建mysql的集群服务时,安装mysql集群服务前,先卸载原来mysql的软件包,不小心将rpm的命令也给卸载掉了,这下惨了,什么也做不了了.在google了翻了好多个页面,甚至官网也看了,没 ...

  5. 小心 CSS3 Transform 引起的 z-index "失效"

    https://www.douban.com/note/343402554/ http://www.jb51.net/css/255811.html 最后我直接removeClass;把transfo ...

  6. [Android Pro] 小心ReleaseByteArrayElements 中的参数问题

    referen to : http://blog.csdn.net/rainlight/article/details/818964 在Sun的官方文档中,关于该函数的用法如下 The array i ...

  7. 桥牌笔记 Skill Level 4 C7 小心将吃

    南主打5H. 看来问题不大,但要小心南的方块AK会阻塞桥路. 如果方块3-2分布,并且将牌也3-2分布,就很容易. 如果红桃4-1分布,那是死定了. 如果方块4-1分布,还有希望完成的! 为了防止东家 ...

  8. OC小实例关于init方法不小心的错误

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  9. 不小心rm删除文件怎么办

    不小心rm删除文件怎么办 rm 命令的副作用越来越显现.而且rm掉之后的东西想找回来很困难.有2个原则: 1 永远不要在root下操作,尤其是rm命令 2 写一个别名,代替rm 我就是在~/.bash ...

  10. 小心Windows7的UTF-8代码页

    目录 第1章小心Windows7的UTF-8代码页    1 1.1 UTF-16与UTF-8相互转换    1 1.1.1 使用Windows API    1 1.1.2 自己编码    1 1. ...

随机推荐

  1. 一个CXF集成SPRING的WEBSERVICE完整实例

    1 首先准备以下JAR包 activation.jar commons-logging-1.1.1.jar cxf-2.5.6.jar jaxb-api-2.2.1.jar jaxb-impl-2.1 ...

  2. Delphi XE2 新增 System.Zip 单元,压缩和解压缩文件

    Delphi XE2 新增 System.Zip 单元, 可用一句话压缩整个文件夹了 单元内主要就是 TZipFile 类, 最方便使用的是它的类方法: TZipFile.ExtractZipFile ...

  3. jquery改造轮播图1

    g改造轮播图1:https://www.cnblogs.com/huanghuali/p/8677338.html <!DOCTYPE html> <html lang=" ...

  4. java中集合

    一. List集合:  一次只存储一个元素 1.常用的list集合是ArrayList (1)在创建这个集合的对象时, 需要指定这个集合存储的数据类型! 否则这个集合的数据是不安全的. (2)与数组的 ...

  5. python中多线程,多进程,多协程概念及编程上的应用

    1, 多线程 线程是进程的一个实体,是CPU进行调度的最小单位,他是比进程更小能独立运行的基本单位. 线程基本不拥有系统资源,只占用一点运行中的资源(如程序计数器,一组寄存器和栈),但是它可以与同属于 ...

  6. abstract方法必须在abstract类中 这句话是对的还是错的?

    对 参考文章:https://zhidao.baidu.com/question/435526297.html interface中所有的方法都是抽象的,抽象类中部分方法是抽象的 实现interfac ...

  7. 网站架构:PHP针对并发访问如何优化?

    1.拆表:大表拆小表(垂直拆,水平拆:分表,分区partition,分片sharding),可以在应用层实现,也可以在数据库层面实现一部分:提高系统性能. 2.分库:把表放到不同的数据库,这也是分布式 ...

  8. jQuery入门讲解

    jQuery设计思想: (1)选择页面元素 css选择器: $(document) 选择整个文档对象, $("#myId") 选择id为myId的页面元素, $("div ...

  9. Leetcode 102 二叉树的层次遍历 Python

    二叉树的层次遍历 给定一个二叉树,返回其按层次遍历的节点值. (即逐层地,从左到右访问所有节点). 例如: 给定二叉树: [3,9,20,null,null,15,7],   3   / \ 9 20 ...

  10. google Agent

    一句话:改HOSTS文件 有时候要查看appengine.google.com的后台,但死活上不去,怎么办?还是那个老办法: 1.在cmd下Ping www.google.com.hk,获得IP地址, ...