this 指向
this指向
全局上下文
无论是否在严格模式下,在全局执行上下文中(在任何函数体外部)this 都指代全局对象
console.log(this === window);//node环境是global函数调用(简单调用)
这是函数的最通常用法,属于全局性调用,因此this在非严格模式下就代表全局对象。严格模式为undefined。
function f1(){
return this;
}
//在浏览器中:
f1() === window; //在浏览器中,全局对象是window
//在Node中:
f1() === global;
function f2(){
"use strict"; // 这里是严格模式
return this;
}
f2() === undefined; // true作为对象的方法(对象方法调用)
当函数作为对象里的方法被调用时,它们的 this 是调用该函数的对象。
this的绑定只受最靠近的成员引用的影响。原型链中方法的
this,同样适用上条原则,取查找过程开始的对象。getter和setter
```javascript
var o = {prop: 37};
o.b = {g: function() {
return this.prop
}, prop: 42};
console.log(o.b.g()); // 42
function a() { this.c = 2 return {b:1} } console.log(new a().c);
## 作为构造函数
当一个函数用作构造函数时(使用`new`关键字),它的`this`被绑定到正在构造的新对象。
- 虽然构造器返回的默认值是`this`所指的那个对象,但它仍可以手动返回其他的对象(如果返回值不是一个对象,则返回`this`对象)
```javascript
function C(){
this.a = 37;
}
var o = new C();
console.log(o.a); // logs 37特殊: 在new Function()里面的this,不论它是在构造函数中,还是函数调用中,this都指向 全局对象。 new Function 相当于函数声明
(function(){
var f = new Function('console.log(this)');
f();
})();
//或
function Foo(){
this.bar = function(){
console.log('bar', this);
var f = new Function('console.log(this)');//等价于声明一个名为f的函数
f();
}
}
var foo = new Foo();
foo.bar();作为一个DOM事件处理函数
当函数被用作事件处理函数时,它的this指向触发事件的元素(一些浏览器在使用非addEventListener的函数动态添加监听函数时不遵守这个约定)。
// 被调用时,将关联的元素变成蓝色
function bluify(e){
console.log(this === e.currentTarget); // 总是 true
// 当 currentTarget 和 target 是同一个对象时为 true
console.log(this === e.target);
this.style.backgroundColor = '#A5D9F3';
}
document.body.addEventListener('click', bluify, false);event对象中target和currentTarget
event.target返回触发事件的元素
event.currentTarget返回绑定事件的元素
作为一个内联事件处理函数
当代码被内联on-event 处理函数调用时,它的this指向监听器所在的DOM元素
<button onclick="alert(this.tagName.toLowerCase());">//button
Show this
</button>箭头函数
在箭头函数中,this与封闭词法上下文的this保持一致。在全局代码中,它将被设置为全局对象:
如果将this传递给call、bind、或者apply,它将被忽略。不过你仍然可以为调用添加参数,不过第一个参数(thisArg)应该设置为null。
参数为函数的情况
将fn函数作为实参传给obj.method,argument0是对象属性的调用方式,所以返回的是arguments自带length属性
var length = 10;
function fn() {
console.log(this.length)
};
var obj = {
length: 5,
method: function (fn) {
fn();
arguments[0]();
fn.call(obj, 12);
}
};
obj.method(fn, 1);改变this指向(apply、call、bind)
通过使用函数继承自Function.prototype 的 call 或 apply 方法将 this 值绑定到调用中的特定对象。
使用 call 和 apply 函数的时候要注意,如果传递给 this 的值不是一个对象,JavaScript 会尝试使用内部 ToObject 操作将其转换为对象。
调用func.bind(someObject)会创建一个与f具有相同函数体和作用域的函数,但是在这个新函数中,this将永久地被绑定到了bind的第一个参数,无论这个函数是如何被调用的。第一个参数为this指向,后续参数为入参,若后期调用时,再次传参,将对在之前bind的入参补充。
bind返回的函数用作构造函数时,bind传入的this将被忽略,实参依旧传入
function a () { console.log('this', this.attr) } var obj = {attr: 2} var b = a.bind(obj); console.log(b()); console.log(new b().attr)
QA
addEventListener与on-event的概念及区别
概念
addEventListener是任务监听器,是W3C DOM 规范中提供的注册事件监听器的方法。
它允许给一个事件注册多个监听器。特别是在使用AJAX库,JavaScript模块,或其他需要第三方库/插件的代码。
它提供了一种更精细的手段控制 listener 的触发阶段。(即可以选择捕获或者冒泡)。
它对任何 DOM 元素都是有效的,而不仅仅只对 HTML 元素有效。
on-event是web平台提供的DOM元素上的一组属性,以帮助管理元素如何对事件反应。
区别
addEventListener 可以在一个目标对象的同一事件类型注册多个回调函数;而on-event只能注册一个回调函数,多次注册,后者会覆盖前者。
addEventListener存在兼容性问题,在IE9之前需要使用attachEvent,同时,this指向会变成window。on-event没有兼容性问题。
on-event中,由于历史原因, 和 元素中的某些元素属性/对象属性实际上是在其父 Window 对象上设置了事件处理器(这些 HTML 命名: onblur, onerror, onfocus, onload, onscroll)。
addEventListener中回调使用箭头函数与普通函数,this指向不同
普通函数和匿名函数在addEventListener中作为处理器,this对象会指向event参数的currentTarget
箭头函数的this还是遵循规定,继承绑定他所在函数的this对象。
Last updated
Was this helpful?