转载

javascript的this简单记忆

一直感觉javascript中的this是一个大坑,虽然一直都有注意,一直都有研究,但是总是会忘记。在这里,总结一下一些简单的规律


不考虑箭头函数的情况下

下面的所有的都是不考虑箭头函数的情况下,因为箭头函数和普通的差别很大


直接调用的都是window

除非是bind绑定过的,其他情况下,直接调用的方法的this都是window。所谓的直接调用,就是直接以method()的形式调用,没有call, apply, new

看几种情况:

function foo(){
   return this;
}
foo(); // window
var obj = {
  foo: function(){ return this; }
}
var foo = obj.foo;
foo(); // window
function Foo(){
  this.foo = function(){
    console.log(this);
  }
  var foo = this.foo;
  foo(); // window
}
new Foo();


谁调用,谁是this
除非是bind绑定过的,一般情况下,谁调用这个方法,那么内部的this就指向这个对象。也就是说obj.method(),那么就指向obj。obj.foo.method(),那么就指向obj.foo

看几个例子:
var obj = {
  foo: function(){ return this; }
}
obj.foo(); // obj调用,所以结果是obj
function foo(){ return this };
var obj = {};
obj.foo = foo;
obj.foo(); // obj调用,所以结果是obj
var obj = {
  bar: function(){ return this; },
  foo: function(){
    return this.bar();
  }
}
obj.foo(); // 在foo中, this是obj, 而this调用的bar, 所以返回的是obj
var obj = {
   bar: {
     foo: function(){ return this }
   }
}
obj.bar.foo(); // obj.bar调用的foo,所以返回的结果是bar
function foo(){
  this.bar = function(){ return this }
  return this.bar();
}
foo(); // 由于foo中的this是window, 所以this.bar()返回的是window
function Foo(){
  this.foo = function(){ console.log(this); }
  this.foo();
}

var object = new Foo(); // 由于this.foo中的this是object,所以this是object


new会生成一个新的this

所有情况下,(箭头函数不能使用new关键字),使用了new以后,会把内部的this指向新生成的对象。

除去bind的情况下,prototype中的this也指向新生成的对象

function Foo(){
  console.log(this); // this指向新生成的对象,object
}
var object = new Foo(); 
function Foo(){
  this.foo = function(){ return this === object; }
}
var object = new Foo();
object.foo(); // 输出true
function Foo(){}
Foo.prototype.foo = function(){ return this === object; }
var object = new Foo();
object.foo(); // 输出true


call, apply是谁,this就是谁

除非是bind的情况,call, apply是谁,那么内部的this就是谁。


注意:如果是基本类型,那么javascript会把基本类型转换成Object的形式

也是看例子:

function foo(){ return this; }
foo.call("a"); // String
typeof foo.call("a"); // object
var obj = {
  foo : function(){ return this; }
}
obj.foo.call(1); // Number
typeof obj.foo.call(1); // object
function Foo(){
  this.foo = function(){ return this; }
}
var object = new Foo();
object.foo.call(1); // Number


bind是谁,this就是谁

除了new这一种特殊情况,bind的对象是谁,那么this也就是谁。即使call, apply也没有权利改变。

注意:如果是基本类型,那么javascript会把基本类型转换成Object的形式

function foo() { return this; } 
foo = foo.bind(1);
foo(); // Number
typeof foo(); // object
function foo() { return this; } 
foo = foo.bind(1);
foo.call("a"); // Number 1
function Foo() { return this; } 
Foo.prototype.foo = (function(){ return this; }).bind(1);
var object = new Foo();
object.foo(); // Number


特殊情况

new这个关键词可以改变方法内部的this,使他指向新生成的对象

function Foo(){ this.foo = function(){ console.log(this === obj) } }
Foo = Foo.bind(1);
var obj = new Foo();
obj.foo(); // 输入true


箭头函数

箭头函数的this是根据定义环境的this来定的,也就是说定义的函数周围的this是什么,它的this就是什么。

而且不会被bind, call, apply所改变

var foo = ()=>{ return this };
foo() // window
var obj = { foo: ()=>this }
obj.foo(); // 由于定义的时候,周围的环境是window,所以返回window
var obj = {
  foo(){
     var bar= ()=>{ return this };
     return bar();
  }
}
obj.foo(); // 由于定义bar的时候,周围环境是obj,所以返回obj
var foo = obj.foo;
foo(); // 同理,这里是window
var foo = ()=>{ return this };
foo = foo.bind(1);
foo(); // window
foo.call(1); // window
foo.apply(1); // window
function Foo(){
  // 箭头函数
  var a = ()=>{
    console.log(this === object); // true
  }
  // 对比普通函数
  var b = function(){
    console.log(this === window); // true
  }
  
  this.foo = function(){
    a(); b();
  }
}
var object = new Foo();
object.foo();
function Foo(){}
// window
Foo.prototype.foo = ()=>{ return this }
// window
var object = new Foo();

object.foo(); // 由于定义foo的时候,周围环境是window,所以这里是window

由于只是我根据经验和资料自己总结的,所以不知道是否有疏忽或者遗漏,如果有问题的地方,欢迎提出。谢谢

免责声明:
杰微刊遵循行业规范,任何转载的稿件都会明确标注来源和链接。
转载目的在于传递更多信息,并不代表杰微刊赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请在30日内与本网联系,我们将在第一时间删除内容。
杰微刊的原创文章,请转载时务必注明文章作者、链接和"来源:杰微刊"。  

原文  http://www.jointforce.com/jfperiodical/article/4188
正文到此结束
Loading...