this踩坑

global this

在浏览器里,在全局范围内,this等价于window对象。

<script type="text/javascript">
     console.log(this === window); //true
script>

 

在浏览器里,在全局范围内,用var声明一个变量和给this或者window添加属性是等价的。

<script type="text/javascript">
     var foo = "bar";
     console.log(this.foo); //logs "bar"
     console.log(window.foo); //logs "bar"
</script>

如果你在声明一个变量的时候没有使用var或者let(ECMAScript 6),你就是在给全局的this添加或者改变属性值。

<script type="text/javascript">
    foo = "bar";
     function testThis() {
       foo = "foo";
     }
     console.log(this.foo); //logs "bar"
     testThis();
     console.log(this.foo); //logs "foo"
script>

function this

无论是在浏览器环境还是node环境, 除了在DOM事件处理程序里或者给出了thisArg(接下来会讲到)外,如果不是用new调用,在函数里面使用this都是指代全局范围的this。

 1 <script type="text/javascript">
 2     foo = "bar";
 3 
 4     function testThis() {
 5       this.foo = "foo";
 6     }
 7 
 8     console.log(this.foo); //logs "bar"
 9     testThis();
10     console.log(this.foo); //logs "foo"
11 script>

如果你在调用函数的时候在前面使用了new,this就会变成一个新的值,和global的this脱离干系。

<script type="text/javascript">
 2     foo = "bar";
 3 
 4     function testThis() {
 5       this.foo = "foo";
 6     }
 7 
 8     console.log(this.foo); //logs "bar"
 9     new testThis();
10     console.log(this.foo); //logs "bar"
11 
12     console.log(new testThis().foo); //logs "foo"
13 script>

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

prototype this

你创建的每一个函数都是函数对象。它们会自动获得一个特殊的属性prototype,你可以给这个属性赋值。当你用new的方式调用一个函数的时候,你就能通过this访问你给prototype赋的值了。

1 function Thing() {
2       console.log(this.foo);
3 }
4 
5 Thing.prototype.foo = "bar";
6 
7 var thing = new Thing(); //logs "bar"
8 console.log(thing.foo);  //logs "bar"

当你使用new为你的函数创建多个实例的时候,这些实例会共享你给prototype设定的值。

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

1 function Thing() {
 2 }
 3 Thing.prototype.foo = "bar";
 4 Thing.prototype.logFoo = function () {
 5     console.log(this.foo);
 6 }
 7 Thing.prototype.setFoo = function (newFoo) {
 8     this.foo = newFoo;
 9 }
10 Thing.prototype.deleteFoo = function () {
11     delete this.foo;
12 }
13 var thing = new Thing();
14 thing.setFoo("foo");
15 thing.logFoo(); //logs "foo";
16 thing.deleteFoo();
17 thing.logFoo(); //logs "bar";
18 thing.foo = "foobar";
19 thing.logFoo(); //logs "foobar";
20 delete thing.foo;
21 thing.logFoo(); //logs "bar";

object this

引用这个对象的其他属性

var obj = {
2     foo: "bar",
3     logFoo: function () {
4         console.log(this.foo);
5     }
6 };
7 
8 obj.logFoo(); //logs "bar"

DOM event this

在一个HTML DOM事件处理程序里面,this始终指向这个处理程序被所绑定到的HTML DOM节点

 1 function Listener() {
 2     document.getElementById("foo").addEventListener("click",
 3        this.handleClick);
 4 }
 5 Listener.prototype.handleClick = function (event) {
 6     console.log(this); //logs "
"
7 } 8 9 var listener = new Listener(); 10 document.getElementById("foo").click();

HTML this

在HTML节点的属性里面,你可以放置JavaScript代码,this指向了这个元素

1 <div id="foo" onclick="console.log(this);">div>
2 <script type="text/javascript">
3 document.getElementById("foo").click(); //logs 
4 script>

jQuery this

和HTML DOM元素节点的事件处理程序一样,在许多情况下JQuery的this都指向HTML元素节点。这在事件处理程序和一些方便的方法中都是管用的,比如$.each

1 <div class="foo bar1">div>
 2 <div class="foo bar2">div>
 3 <script type="text/javascript">
 4 $(".foo").each(function () {
 5     console.log(this); //logs 
6 }); 7 $(".foo").on("click", function () { 8 console.log(this); //logs
9 }); 10 $(".foo").each(function () { 11 this.click(); 12 }); 13 script>

你可能感兴趣的:(this踩坑)