1 全局高低文中的this
在浏览器引擎的全局运转高低文中(在任何函数体外部),this 指代全局对象,不管是不是在严厉形式下。
<script>
'use strict';
console.log(this === window); // true
</script>
<script>
console.log(this === window); // true
</script>
在node的全局高低文,发明this是一个空对象,不管是不是在严厉形式下。
在函数内部,this的值取决于函数是怎样挪用的。
2 直接挪用函数中的this
在非严厉的形式下,this的值默以为全局对象,window或许global。
在严厉形式下,this的值为undefined。
平常我们应用this的场景,都不是指代全局对象,所以涌现这类this是全局对象或许undefined的时刻 往往是我们出错了
<script>
'use strict';
function f1 () {
console.log(this === window);
}
f1();// false
</script>
<script>
function f1 () {
console.log(this === window);
}
f1();// true
</script>
3 挪用对象要领中的this
当以对象的要领挪用函数时,函数中的this指向挪用该函数的要领
var o = {
prop: 37,
f: function() {
return this.prop;
}
};
console.log(o.f()); // logs 37
/**********************************/
var o = {prop: 37};
function independent() {
return this.prop;
}
o.f = independent;
console.log(o.f()); // logs 37 //只取决于末了的函数挪用
函数的this指向挪用它的近来对象,这里independent函数中的this指向的是o.b 而不是o。
o.b = {
g: independent,
prop: 42
};
console.log(o.b.g()); // logs 42
以下原型链和getter、setter中的this,都是挪用对象要领中this的场景。
之前犯过一个反过来的毛病,在一个对象中定义的要领中挪用this,然则运用要领的时刻没有经由历程对象挪用,所以this为undefined而不是本来的对象。
3.1 原型链中的 this
雷同的观点在定义在原型链中的要领也是一致的。假如该要领存在于一个对象的原型链上,那末this指向的是挪用这个要领的对象,表现得好像是这个要领就存在于这个对象上一样。
var o = {
f : function(){
return this.a + this.b;
}
};
var p = Object.create(o);
p.a = 1;
p.b = 4;
console.log(p.f()); // 5
在这个例子中,对象p没有属于它自己的f属性,它的f属性继续自它的原型。然则这关于终究在o中找到f属性的查找历程来讲没有关系;查找历程首先从p.f的援用最先,所以函数中的this指向p。也就是说,由于f是作为p的要领挪用的,所以它的this指向了p。这是JavaScript的原型继续中的一个风趣的特征。
3.2 getter 与 setter 中的 this
再次,雷同的观点也适用时的函数作为一个 getter 或许 一个setter挪用。作为getter或setter函数都邑绑定 this 到从设置属性或获得属性的谁人对象。
function modulus(){
return Math.sqrt(this.re * this.re + this.im * this.im);
}
var o = {
re: 1,
im: -1,
get phase(){
return Math.atan2(this.im, this.re);
}
};
Object.defineProperty(o, 'modulus', {
get: modulus, enumerable:true, configurable:true});
console.log(o.phase, o.modulus); // logs -0.78 1.414
4 组织函数中的 this
当一个函数被作为一个组织函数来运用(运用new关键字),它的this与即将被建立的新对象绑定。
注重:当组织器返回的默许值是一个this援用的对象时,能够手动设置返回其他的对象,假如返回值不是一个对象,返回this。
function C(){
this.a = 37;
}
var o = new C();
console.log(o.a); // logs 37
function C2(){
this.a = 37;
return {a:38};
}
o = new C2();
console.log(o.a); // logs 38
在末了的例子中(C2),由于在挪用组织函数的历程当中,手动的设置了返回对象,与this绑定的默许对象被作废(本质上这使得语句“this.a = 37;”成了“僵尸”代码,实际上并非真正的“僵尸”,这条语句实行了然则关于外部没有任何影响,因而完全能够疏忽它)。
5 call 和 apply
call和apply能够指定函数实行时this的指向。
当一个函数的函数体中运用了this关键字时,经由历程一切函数都从Function对象的原型中继续的call()要领和apply()要领挪用时,它的值能够绑定到一个指定的对象上。
function add(c, d){
return this.a + this.b + c + d;
}
var o = {a:1, b:3};
// The first parameter is the object to use as 'this', subsequent parameters are passed as
// arguments in the function call
add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16
// The first parameter is the object to use as 'this', the second is an array whose
// members are used as the arguments in the function call
add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34
运用 call 和 apply 函数的时刻要注重,假如通报的 this 值不是一个对象,JavaScript 将会尝试运用内部 ToObject 操纵将其转换为对象。因而,假如通报的值是一个原始值比方 7 或 ‘foo’ ,那末就会运用相干组织函数将它转换为对象,所以原始值 7 经由历程new Number(7)被转换为对象,而字符串’foo’运用 new String(‘foo’) 转化为对象,比方:
function bar() {
console.log(Object.prototype.toString.call(this));
}
bar.call(7); // [object Number]
6 bind 要领
ECMAScript 5 引入了 Function.prototype.bind。挪用f.bind(someObject)会建立一个与f具有雷同函数体和作用域的函数,然则在这个新函数中,this将永远地被绑定到了bind的第一个参数,不管这个函数是怎样被挪用的。
能够看到,call和apply是不转变本来的函数,只是在实行的时刻指定函数的this,而bind要领则是生成了一个this指向牢固的函数,
function f(){
return this.a;
}
var g = f.bind({a:"azerty"});
console.log(g()); // azerty
var o = {a:37, f:f, g:g};
console.log(o.f(), o.g()); // 37, azerty
在ES6的语法中,箭头函数默许绑定当前函数声明环境的this。
7 DOM事宜处置惩罚函数中的 this
当函数被用作事宜处置惩罚函数时,它的this指向函数所绑定的DOM对象。
event.currentTarget指向事宜所绑定的元素,而event.target一直指向事宜发作时的元素
所以this 一直和 event.currentTarget 雷同。
<body>
<div id="wrapper" style="height:200px; background: red">
<input id="inner" type="button" value="inner" />
</div>
</body>
<script>
function func1 (e) {
console.log('wrapper')
console.log('this');
console.log(this);
console.log("e.target");
console.log(e.target);
console.log('e.currentTarget');
console.log(e.currentTarget);
}
function func2 (e) {
console.log('inner')
console.log('this');
console.log(this);
console.log("e.target");
console.log(e.target);
console.log('e.currentTarget');
console.log(e.currentTarget);
}
document.getElementById("wrapper").addEventListener('click',func1);
document.getElementById("inner").addEventListener('click',func2);
</script>
8 内联事宜处置惩罚函数中的 this
当代码被内联处置惩罚函数挪用时,它的this指向监听器地点的DOM元素:
<button onclick="alert(this.tagName.toLowerCase());">
Show this
</button>
//上面的alert会显现button。注重只要外层代码中的this是如许设置。
<button onclick="alert((function(){return this})());">
Show inner this
</button>
在这类情况下,没有设置内部函数的 this,所以它指向 global/window 对象(即非严厉形式下挪用的函数未设置 this 时指向的默许对象)。
本文绝大多数内容参考自: https://developer.mozilla.org…
仅作少量修正