JS中this的指向

这篇具有很好参考价值的文章主要介绍了JS中this的指向。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

JS中this的指向

  1. this永远指向一个对象

  2. this的指向完全取决于函数调用的位置

  3. JavaScript支持运行环境动态切换,this的指向是动态的

全局上下文(Global Context)

在全局执行环境中(在任何函数体外部),this都是指向全局对象,在浏览器中,window对象即是全局对象。

// 在浏览器中,window 对象同时也是全局对象:
console.log(this === window); // true

a = 37;
console.log(window.a); // 37

this.b = "MDN";
console.log(window.b)  // "MDN"
console.log(b)         // "MDN"
console.log(this.b)    // "MDN"
JS中this的指向

函数上下文(Function Context)

在函数内部,this的值取决于函数的调用方式。这包括普通函数调用、作为对象的方法调用、构造函数调用、以及通过call、apply或bind方法调用。

普通函数调用

如果一个函数不是作为对象的方法被调用,而是作为普通函数被调用,那么 this 通常指向全局对象(在严格模式下,this 是 undefined)

var name = 'window';
var doSth = function(){
  console.log(this.name);
}
doSth();  // 'window'

let 不给顶层对象添加属性(浏览器为Window)

let name2 = 'window2';
let doSth2 = function(){
  console.log(this === window);
  console.log(this.name2);
}
doSth2() // true, undefined

严格模式下,正常函数中的 this 行为不同,如未定义输出undefined

'use strict'
var name3 = 'window3';
var doSth3 = function(){
    console.log(typeof this === 'undefined');
    console.log(this.name3);
}
doSth3();

window.doSth3();

JS中this的指向JS中this的指向

作为对象的方法调用

如果一个函数作为对象的方法被调用,this 就指向这个对象

var name = 'window';
var doSth = function(){
    console.log(this.name);
}
var student = {
    name: 'dog',
    doSth: doSth,
    other: {
        name: 'other',
        doSth: doSth,
    }
}

student.doSth(); // 'dog'
// call like this
student.doSth.call(student);

student.other.doSth(); // 'other'
// call like this
student.other.doSth.call(student.other);
JS中this的指向

将对象中的函数分配给变量,实际上又是一个普通函数,所以使用普通函数的规则(默认绑定)。

var studentDoSth = student.doSth;
studentDoSth(); // 'window'
// call like this :
studentDoSth.call(undefined);
JS中this的指向

o.f() 被调用时,函数内的 this 将绑定到 o 对象

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

console.log(o.f()); // 37

也可以先定义函数,然后再将其附属到o.f,这样做的结果是一样的

var o = {prop: 37};

function independent() {
  return this.prop;
}

o.f = independent;

console.log(o.f()); // 37

原型链中的 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
构造函数调用

当一个函数用作构造函数时(使用new关键字),this 指向新创建的对象。

function Foo() {
  this.name = 'Test';
  console.log(this);
}

// 使用new关键字调用
var obj = new Foo();  // this指向新创建的obj对象
console.log(obj.name); // 输出 'Test'

// 不使用new关键字调用
Foo();  // this指向全局对象(非严格模式)或undefined(严格模式)
console.log(window.name); // 在非严格模式下,输出 'Test'
JS中this的指向
  1. 如果构造函数没有返回对象(也就是没有返回值或者返回非对象),那么new表达式的结果就是新创建并且被this关键字指向的对象。
  2. 如果构造函数返回一个对象,那么new表达式的结果就是这个返回的对象。
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
JS中this的指向
箭头函数

箭头函数上下文(Arrow Function Context)
箭头函数不绑定this,它会捕获其所在(即定义的位置)的上下文的this值作为自己的this值。

this 被设置为它被创建时的环境

var name = 'window';
var student = {
    name: 'dog',
    doSth: function(){
        // var self = this;
        var arrowDoSth = () => {
            // console.log(self.name);
            console.log(this.name);
        }
        arrowDoSth();
    },
    arrowDoSth2: () => {
        console.log(this.name);
    }
}
student.doSth(); // 'dog'
student.arrowDoSth2(); // 'window'
JS中this的指向

不能通过call、apply、bind来绑定箭头函数的this(它本身没有this

var globalObject = this;
var foo = (() => this);
console.log(foo() === globalObject); // true

// 作为对象的一个方法调用
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

call、apply、bind可以绑定缓存箭头函数上面的普通函数的this

var student = {
    name: 'dog',
    doSth: function(){
        console.log(this.name);
        return () => {
            console.log('arrowFn:', this.name);
        }
    }
}
var person = {
    name: 'person',
}
student.doSth().call(person); // 'dog'  'arrowFn:' 'dog'
student.doSth.call(person)(); // 'person' 'arrowFn:' 'person'
回调函数

回调函数中 this 的指向,决定于执行回调函数 时的执行上下文环境

(function(){
  console.log(this); // window
})();

setTimeout(() => {
  console.log(this); // window
}, 0);

setTimeout(function(){
  console.log(this); // window
}, 0);

组合使用

第一个setTimeout,执行obj.getage 之后,相当于setTimeout的回调是一个匿名函数,执行的时候,函数内部未设置this的指向。相当于是普通函数调用。所以this默认指向window,所以结果是undefined。

第二个setTimeout,传给setTimeout的也是一个匿名回调函数,执行匿名函数,执行到 obj.getage() 的时候,getage函数里的this,指向的就是obj了,所以能打印出10。遵循 谁调用产生 this指针的函数,this就指向谁的规则

var obj = {
    age:10,
    getage:function(){
        console.log(this.age)
    }
}

setTimeout(obj.getage,1000)   // undefined

setTimeout(function(){
    obj.getage()  // 10
},1000)
let obj={
  a:222,
  fn:function(){    
    setTimeout(()=>{console.log(this.a)});
  }
};
obj.fn(); // 222
var name = 'window'; 
var A = {
  name: 'A',
  sayHello: () => {
    console.log(this.name)
  }
}

A.sayHello(); // 输出的是window,根据刚才讲的规则就可以判断

// 那如何改造成永远绑定A呢:

var name = 'window'; 
var A = {
  name: 'A',
  sayHello: function(){
    var s = () => console.log(this.name)
    return s//返回箭头函数s
  }
}

var sayHello = A.sayHello();
sayHello();// 输出A 
let obj = {
  value: 'Hello, World',
  print: function() {
    setTimeout(function() {
      console.log(this.value);
    }, 1000);
  }
};

obj.print();  // 输出:undefined(严格模式)或者一个全局value(非严格模式)


let obj = {
  value: 'Hello, World',
  print: function() {
    setTimeout(() => {
      console.log(this.value);  // 输出:Hello, World
    }, 1000);
  }
};

// 或者

let obj = {
  value: 'Hello, World',
  print: function() {
    setTimeout(function() {
      console.log(this.value);
    }.bind(this), 1000);
  }
};

事件处理器上下文(Event Handler Context)

在DOM事件处理器中,this通常指向触发事件的元素。

在事件处理函数(或者说事件监听器)中,this通常指向触发事件的 DOM 元素。第一个事件监听器中,this打印出来的是按钮元素本身。

bluify函数作为事件处理函数使用,因此在这个函数中,this指向触发点击事件的按钮元素。

let btn = document.getElementById('btn');

btn.addEventListener('click', function () {
  console.log(this);  // button
});

btn.addEventListener('click', bluify, false);

function bluify(e) {
  console.log(this === e.currentTarget); // 总是 true

  // 当 currentTarget 和 target 是同一个对象时为 true
  console.log(this === e.target);
  this.style.backgroundColor = '#A5D9F3';
}

通过 call,apply,bind 改变this指向

  • call(a, b, c方法接收三个参数,第一个是this指向,第二个,三个是传递给函数的实参,可以是数字,字符串,数组等类型的数据类型都可以

  • apply(a, [b])和call基本上一致,唯一区别在于传参方式,apply把需要传递给fn()的参数放到一个数组(或者类数组)中传递进去,虽然写的是一个数组,但是也相当于给fn()一个个的传递

  • bind(a, b, c:语法和call一模一样,区别在于立即执行还是等待执行文章来源地址https://www.toymoban.com/news/detail-466401.html

fn.bind(第一个参数是this的指向)
fn.call(第一个参数是this的指向,parma2,param3...)
fn.apply(第一个参数是this的指向,[parma2,parma3..])
//call()方法:改变fn中的this,并且把fn立即执行
fn.call(obj, 1, 2); 
//bind()方法:改变fn中的this,fn并不执行
fn.bind(obj, 1, 2); 
var obj = {
  name:'111',
  getName:function(){
    console.log(this.name)
  }
};

var otherObj = {
  name:'222',
};

var name = '333';
        
obj.getName();               // 111
obj.getName.call();          // 333
obj.getName.call(otherObj);  // 222
obj.getName.apply();         // 333
obj.getName.apply(otherObj); // 222
obj.getName.bind(this)();    // 333
obj.getName.bind(otherObj)();// 222

到了这里,关于JS中this的指向的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JS中this的指向

    this永远指向一个对象 this的指向完全取决于函数调用的位置 JavaScript支持运行环境动态切换,this的指向是动态的 全局上下文(Global Context) 在全局执行环境中(在任何函数体外部),this都是指向全局对象,在浏览器中,window对象即是全局对象。 函数上下文(Function Context)

    2024年02月07日
    浏览(27)
  • JS 能改变this指向的方法

    JavaScript中的this非常重要,它用于引用当前函数所属的对象。但是,有时候我们需要在不同的上下文中使用相同的函数,这就需要改变this指向。在JavaScript中,有几种方法可以实现这一目标。 call方法是JS中最基本的改变this指向的方法之一。它允许您将一个函数作为另一

    2024年02月08日
    浏览(29)
  • Js:apply/call/bind、作用域/闭包、this指向(普通,箭头,JS/Vue的this)

    共同点: apply()、call() 和 bind() 方法 三者作用都是 改变this指向。 接收的第一个参数都是this要指向的对象 区别: apply只有两个参数,第二个参数为数组; call和bind传参相同,多个参数依次传入的; call和apply都是对函数进行直接调用(立即执行),而bind方法不会立即调用函数

    2023年04月08日
    浏览(82)
  • 前端面试题-js-new关键字-this指向-js事件流-防抖节流

    1.创建一个简单的空对象 2.原型的绑定,确定对象O的原型链 3.绑定this对象为O,传入参数;执行Person构造函数,进行属性和方法的赋值操作 4.返回结果 普通函数的this指向 函数的this指向有一个基本的原则,谁调用的函数,函数的this就指向谁,否则指向全局 箭头函数的this指向

    2024年01月25日
    浏览(39)
  • React之组件的分类、使用,事件对象,this指向问题,修改状态以及受控组件与非受控组件

    组件是 React 开发(现代前端开发)中最重要的内容 组件允许你将 UI 拆分为独立、可复用的部分,每个部分都可以独立的思考 组合多个组件(组装乐高积木)实现完整的页面功能 特点:独立、可复用、可组合 组件包含三部分:HTML/CSS/JS 展示页面中的可复用部分 函数组件:使

    2024年02月16日
    浏览(34)
  • this指向性问题

    this的查找规则会逐层往上查找,最终位全局window 优先级问题:显式绑定(显式绑定与new绑定没有可比性)new绑定隐式绑定默认绑定 在编程中,this 是一个,代表当前对象或者函数的执行环境。this 的指向性问题是指在不同的情况下,this 指向的对象不同,从而影响代码的

    2024年02月11日
    浏览(31)
  • Java狗血神坑记录A a = new A();A b = a;a b指向同一个对象

    业务场景,有一个订单更新逻辑,测试订单不需要审批。 订单类型可编辑,如果是从测试类型–》正式类型,需要以上审批状态置为未审批,重新审批。 实际项目已经是七手八手的了,在原来的*山继续修修补补。 大致逻辑有下面这些东西

    2024年02月11日
    浏览(36)
  • 箭头函数的 this 指向哪里?

    箭头函数不同于传统 JS 中的函数,箭头函数并没有属于自己的 this,他所谓的 this 是捕获其所在上下文的 this 值,作为自己的 this 值,并且由于没有属于自己的 this,所以是不会被 new 调用的,这个所谓的 this 也不会被改变。可以用 Babel 理解一下箭头函数:

    2023年04月26日
    浏览(87)
  • 前端面试——关于this指向问题?

    想要知道关于this的指向问题,首先要了解this的绑定规则。那么this到底是什么样的绑定规则呢?一起来研究一下吧! 绑定一:默认绑定 绑定二:饮食绑定 绑定三:显示绑定 绑定四:隐式绑定 什么情况下使用默认绑定呢?独立函数调用。独立的函数调用我们可以理解成函数

    2024年01月25日
    浏览(39)
  • JavaScript全解析——this指向

    本系列内容为JS全解析,为千锋教育资深前端老师独家创作 致力于为大家讲解清晰JavaScript相关知识点,含有丰富的代码案例及讲解。如果感觉对大家有帮助的话,可以【点个关注】持续追更~ this 是一个,是一个使用在作用域内的 作用域分为 全局作用域和局部作

    2024年02月03日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包