javascript 里面的 this

本文深入解析JavaScript中的this关键字,探讨其在不同上下文中的行为,包括全局上下文、函数调用、对象方法、原型链、构造函数及DOM事件处理等场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、全局上下文:this指的是全局对象。

console.log(this === window);//true

二、函数上下文:在函数内部,this值取决于函数被调用的方式。

1.简单调用

非严格模式下,this的值不是通过调用设置的, this默认是全局对象

function fn(){return this;} fn() == window;

严格模式 undefined

2.call或者apply
如果把一个this从一个上下文传到另一个上下文,就要用call或者apply方法

// 一个对象可以作为call和apply的第一个参数,并且this会被绑定到这个对象。
var obj = {a: 'Custom'};
// 这个属性是在global对象定义的。
var a = 'Global';
function whatsThis(arg) {
  return this.a;  // this的值取决于函数的调用方式
}
whatsThis();          // 直接调用,      返回'Global'
whatsThis.call(obj);  // 通过call调用,  返回'Custom'
whatsThis.apply(obj); // 通过apply调用 ,返回'Custom'

函数使用this关键字的时候,它的值可以被绑定到调用中的一个特定的对象,使所有函数继承来自Function.prototype的call或者apply方法

function add(c, d) {
  return this.a + this.b + c + d;
}
var o = {a: 1, b: 3};
// 第一个参数是作为‘this’使用的对象
// 后续参数作为参数传递给函数调用
add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16
// 第一个参数也是作为‘this’使用的对象
// 第二个参数是一个数组,数组里的元素用作函数调用中的参数
add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34

使用call或者apply时候要注意,如果传入的第一个参数不是对象,将被隐式的转换为对象

function bar() {
  console.log(Object.prototype.toString.call(this));
}
//原始值 7 被隐式转换为对象
bar.call(7); // [object Number]

3.bind方法
f.bind(someobj)会创建一个与f具有相同作用域和函数体的函数,但在新函数里面this被永久的绑定到了bind的第一个参数,无论这个函数是如何被调用的。

function f(){
  return this.a;
}
//this被固定到了传入的对象上
var g = f.bind({a:"azerty"});
console.log(g()); // azerty
var h = g.bind({a:'yoo'}); //bind只生效一次!
console.log(h()); // azerty
var o = {a:37, f:f, g:g, h:h};
console.log(o.f(), o.g(), o.h()); // 37, azerty, azerty

4.箭头函数
this与封闭词法中上下文this保持一致,他将被默认设置为全局对象

var golbalobj = this;
var foo=(()=>this);
console.log(foo === golbalobj)

如果将thisArg传递给call、bind、或者apply,它将被忽略。

// 接着上面的代码
// 作为对象的一个方法调用
var obj = {foo: foo};
console.log(obj.foo() === globalObject); // true
// 尝试使用call来设定this
console.log(foo.call(obj) === globalObject); // true
// 尝试使用bind来设定this
foo = foo.bind(obj);
console.log(foo() === globalObject); // true

5.作为对象的方法:当以对象里的方法调用时,this指的是调用该函数的对象

var o = {
  prop: 37,
  f: function() {
    return this.prop;
  }
};
console.log(o.f()); // logs 37

6.原型链里的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

7.getter 与 setter 中的 this: 用作getter或setter的函数都会把 this 绑定到正在设置或获取属性的对象。
8.当一个函数用作构造函数时(使用new关键字),它的this被绑定到正在构造的新对象。
9.作为一个dom事件处理函数:当函数被用作事件处理函数时,它的this指向触发事件的元素(一些浏览器在使用非addEventListener的函数动态添加监听函数时不遵守这个约定)

// 被调用时,将关联的元素变成蓝色
function bluify(e){
  console.log(this === e.currentTarget); // 总是 true
  // 当 currentTarget 和 target 是同一个对象时为 true
  console.log(this === e.target);        
  this.style.backgroundColor = '#A5D9F3';
}
// 获取文档中的所有元素的列表
var elements = document.getElementsByTagName('*');
// 将bluify作为元素的点击监听函数,当元素被点击时,就会变成蓝色
for(var i=0 ; i<elements.length ; i++){
  elements[i].addEventListener('click', bluify, false);
}

10.作为一个内联事件处理函数:当代码被内联on-event 处理函数调用时,它的this指向监听器所在的DOM元素

<button onclick="alert(this.tagName.toLowerCase());">
  Show this
</button>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值