JavaScript中的this的一些用法

一、global this

  • 总结起来就是:在浏览器里面this是老大,它等价于window对象,如果你声明一些全局变量(不管在任何地方),这些变量都会作为this的属性。
  • 在node里面,有两种执行JavaScript代码的方式,一种是直接执行写好的JavaScript文件,另外一种是直接在里面执行一行行代码。
  • 对于直接运行一行行JavaScript代码的方式,global才是老大,this和它是等价的。在这种情况下,和浏览器比较相似
  • 也就是声明一些全局变量会自动添加给老大global,顺带也会添加给this
  • 但是在node里面直接脚本文件就不一样了,你声明的全局变量不会自动添加到this,但是会添加到global对象。所以相同点是,在全局范围内,全局变量终究是属于老大的
二、function this

  • 如果不是用new调用,在函数里面使用this都是指代全局范围的this
  • 函数里面的this其实相对比较好理解,如果我们在一个函数里面使用this,需要注意的就是我们调用函数的方式,如果是正常的方式调用函数,this指代全局的this
  • 如果我们加一个new,这个函数就变成了一个构造函数,我们就创建了一个实例,this指代这个实例,这个和其他面向对象的语言很像
  • 另外,写JavaScript很常做的一件事就是绑定事件处理程序,也就是诸如button.addEventListener(‘click’, fn, false)之类的,如果在fn里面需要使用thisthis指代事件处理程序对应的对象,也就是button
三、prototype this

  • 你创建的每一个函数都是函数对象。它们会自动获得一个特殊的属性prototype,你可以给这个属性赋值。当你用new的方式调用一个函数的时候,你就能通过this访问你给prototype赋的值了
     
     
1
2
3
4
5
6
7
8
     
     
function Thing() {
console.log( this.foo);
}
Thing.prototype.foo = "bar";
var thing = new Thing(); //logs "bar"
console.log(thing.foo); //logs "bar"
  • 当你使用new为你的函数创建多个实例的时候,这些实例会共享你给prototype设定的值。当你调用this.foo的时候,都会返回相同的值,除非你在某个实例里面重写了自己的this.foo

  • 实例里面的this是一个特殊的对象。你可以把this想成一种获取prototype的值的一种方式。当你在一个实例里面直接给this添加属性的时候,会隐藏prototype中与之同名的属性。如果你想访问prototype中的这个属性值而不是你自己设定的属性值,你可以通过在实例里面删除你自己添加的属性的方式来实现

  • 通过一个函数创建的实例会共享这个函数的prototype属性的值,如果你给这个函数的prototype赋值一个Array,那么所有的实例都会共享这个Array,除非你在实例里面重写了这个Array,这种情况下,函数的prototypeArray就会被隐藏掉

  • 给一个函数的prototype赋值一个Array通常是一个错误的做法。如果你想每一个实例有他们专属的Array,你应该在函数里面创建而不是在prototype里面创建
  • 实际上你可以通过把多个函数的prototype链接起来的从而形成一个原型链,因此this就会魔法般地沿着这条原型链往上查找直到找你你需要引用的值
     
     
1
2
3
4
5
6
7
8
9
10
11
12
     
     
function Thing1() {
Thing1.prototype.foo = "bar";
}
function Thing2() {
}
Thing2.prototype = new Thing1();
var thing = new Thing2();
console.log(thing.foo); //logs "bar"
四、object this

  • 在一个对象的一个函数里,你可以通过this来引用这个对象的其他属性。这个用new来新建一个实例是不一样的
     
     
1
2
3
4
5
6
7
8
     
     
var obj = {
foo: "bar",
logFoo: function () {
console.log( this.foo);
}
};
obj.logFoo(); //logs "bar"
  • 注意,没有使用new,没有使用Object.create,也没有使用函数调用创建一个对象。你也可以将对象当作一个实例将函数绑定到上面
     
     
1
2
3
4
5
6
7
8
9
     
     
var obj = {
foo: "bar"
};
function logFoo() {
console.log( this.foo);
}
logFoo.apply(obj); //logs "bar"
五、DOM event this

  • 在一个HTML DOM事件处理程序里面,this始终指向这个处理程序被所绑定到的HTML DOM节点
     
     
1
2
3
4
5
6
7
8
9
10
     
     
function Listener() {
document.getElementById( "foo").addEventListener( "click",
this.handleClick);
}
Listener.prototype.handleClick = function (event) {
console.log( this); //logs "<div id="foo"></div>"
}
var listener = new Listener();
document.getElementById( "foo").click();
  • 除非你自己通过bind切换了上下文
     
     
1
2
3
4
5
6
7
8
9
10
     
     
function Listener() {
document.getElementById( "foo").addEventListener( "click",
this.handleClick.bind( this));
}
Listener.prototype.handleClick = function (event) {
console.log( this); //logs Listener {handleClick: function}
}
var listener = new Listener();
document.getElementById( "foo").click();
六、HTML this

  • HTML节点的属性里面,你可以放置JavaScript代码,this指向了这个元素
     
     
1
2
3
4
     
     
<div id= "foo" οnclick= "console.log(this);"> </div>
<script type= "text/javascript">
document.getElementById( "foo").click(); //logs <div id="foo"...
< /script>
七、override this

  • 你不能重写this,因为它是保留字
     
     
1
2
3
4
     
     
function test () {
var this = {}; // Uncaught SyntaxError: Unexpected token this
}
eval this
  • 你可以通过eval来访问this
     
     
1
2
3
4
5
6
7
8
9
10
11
12
     
     
function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
eval( "console.log(this.foo)"); //logs "bar"
}
var thing = new Thing();
thing.logFoo();
  • 这会造成一个安全问题,除非不用eval,没有其他方式来避免这个问题
八、with this

  • 你可以通过with来将this添加到当前的执行环境,并且读写this的属性的时候不需要通过this
     
     
1
2
3
4
5
6
7
8
9
10
11
12
13
     
     
function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
with ( this) {
console.log(foo);
foo = "foo";
}
}
var thing = new Thing();
thing.logFoo(); // logs "bar"
console.log(thing.foo); // logs "foo"
  • 许多人认为这样使用是不好的因为with本身就饱受争议
九、jQuery this

  • HTML DOM元素节点的事件处理程序一样,在许多情况下JQuerythis都指向HTML元素节点。这在事件处理程序和一些方便的方法中都是管用的,比如$.each
     
     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
     
     
<div class= "foo bar1"> </div>
<div class= "foo bar2"> </div>
<script type= "text/javascript">
$( ".foo").each( function () {
console.log( this); //logs <div class="foo...
});
$( ".foo").on( "click", function () {
console.log( this); //logs <div class="foo...
});
$( ".foo").each( function () {
this.click();
});
< /script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值