JavaScript篇章

JavaScript中的this

2019-12-05  本文已影响0人  CodeMT

thisJavaScript语言中的一个关键字 它是函数运行时,在函数体内部自动生成的一个对象,只能在函数体内部使用。

隐式绑定

关于this,一般来说,谁调用了方法,该方法的this就指向谁

例如:

function foo() {    
  console.log(this);    
  console.log(this.a);
}
var a = 3;
var obj = {    
  a:2,    
  foo:foo
};
foo(); //输出window,3
obj.foo();//输出obj,2

如果存在多次调用,对象属性引用链只有一层或者说最后一层在调用位置中起作用

例如:

function foo(){    
  console.log(this.a);
}
var obj2 = {    
  a:42,    
  foo:foo
}
var obj1 = {    
  a:2,    
  obj2:obj2
}

obj1.obj2.foo();//42

隐式丢失

一个最常见的this绑定问题就是被隐式绑定的函数会丢失绑定对象,也就是说它会应用默认绑定,从而把this绑定到全局对象或者undefined上,取决于是否是严格模式。

function foo() {    
  console.log(this.a);
}
var obj = {    
  a:2,    
  foo:foo
}

var a = 3;//a是全局对象的属性
var bar = obj.foo;//函数别名
bar();//3

一个更常见的情况发生在传入回调函数是:

function foo() {    
  console.log(this.a);
}
function doFoo(fn) {    
  //fn其实引用的是foo    
  fn(); //调用位置
}
var obj = {    
  a:2,    
  foo:foo
}
var a = 3;//a是全局对象的属性
doFoo(obj.foo);//3

显式绑定

简单的说,就是指定this,如:callapplybind、和new绑定等

硬绑定

function foo(b){    
  console.log(this.a,b);    
  return this.a+b;
}
var obj = {    
  a:2
};
var bar = function() {    
  return foo.apply(obj,arguments);
};
var b = bar(3); // 2 3

console.log(b);//5
function foo(b){    
  console.log(this.a,b);    
  return this.a+b;
}
var obj = {    
  a:2
};
var bar = foo.bind(obj);
var b = bar(3);// 2 3

console.log(b);//5

new绑定

在传统面向类的语言中,使用new初始化类的时候会调用类中的构造函数,但是JSnew的机制实际上和面向类的语言完全不同。 使用new来调用函数,或则说发生构造函数调用时,会自动执行下面的操作:

function foo(a){    
  this.a = a;
}
var bar = new foo(2);

console.log(bar.a);//2

this的优先级

毫无疑问,默认绑定的优先级是四条规则中最低的,所以我们可以先不考虑它。 隐式绑定和显式绑定哪个优先级更高?

function foo(a){    
  console.log(this.a);
}
var obj1 = {    
  a:2,    
  foo:foo
};
var obj2 = {    
  a:3,   
  foo:foo
};
obj1.foo();//2
obj2.foo();//3
obj1.foo.call(obj2);//3
obj2.foo.call(obj1);//2
function foo(a){    
  this.a = a;
}
var obj1 = {    
  foo:foo
};
var obj2 = {};
obj1.foo(2);
console.log(obj1.a);//2 

obj1.foo.call(obj2,3);
console.log(obj2.a);//3 

var bar = new obj1.foo(4);
console.log(obj1.a);//2
console.log(bar.a);//4
function foo(a){    
  this.a = a;
}
var obj1 = {};
var bar = foo.bind(obj1);
bar(2);
console.log(obj1.a);//2 

bar baz = new bar(3);
console.log(obj1.a);//2
console.log(baz.z);//3
function foo(p1,p2){    
  this.val = p1 + p2;
}
var bar = foo.bind(this,1);
var baz = new bar(2);

console.log(baz.val);//3

柯里化:在直觉上,柯里化声称“如果你固定某些参数,你将得到接受余下参数的一个函数”。所以对于有两个变量的函数yx,如果固定了 y = 2,则得到有一个变量的函数2x

This在箭头函数中的应用

箭头函数不适用this的四种标准规则,而是根据外层(函数或则全局)作用域来决定this

function foo(){    
  return (a) => {        
    console.log(this.a);    
  }
}
var obj1 = {    
  a:2
};
var obj2 = {    
  a:3
};
var bar = foo.call(obj1);
bar.call(obj2);//2,不是3

总结

如果要判断一个运行中的函数的this绑定,就需要找到这个函数的直接调用位置。找到之后就可以顺序应用下面这四条规则来判断this的绑定对象。

上一篇下一篇

猜你喜欢

热点阅读