JavaScript中改变this指向

102 阅读3分钟

一、this的理解

this 是函数的内置对象,谁调用这个函数或方法,this 关键字就指向谁
全局作用域或者普通函数中 this 指向全局对象 window
对象调用 对象.函数名( ) 谁调用指向谁 (.前面是谁就指向谁)
在构造函数或者构造函数原型对象中 this 指向构造函数的实例
箭头函数中指向外层作用域的 this

二、使用call改变this指向

语法:函数名.call(第一个参数,…………)

语法: 函数名.call(你要改变的函数的 this 指向, 第二个参数开始,依次是给函数传递的参数) 会直接把函数给调用 第一个参数如果不写或者写一个 null,表示 window

let a = 10;
function fn(b) {
    console.log(this);
    console.log(b);
}
fn.call(a,"gg");  // 直接调用
// Number {10}
// gg

使用call需要注意:

  • 第一个参数就是对象(你想要this指向的那个对象)
  • 其他参数可以有任意多个,给调用call()方法函数的实参
fun.call(obj,n1,n2)
n1和n2为fun函数的实参
  • call方法使用之后或自动执行该函数

三、使用apply改变this指向

语法:函数名.apply(对象,[arr])

语法: 函数名.apply(你要改变的函数的 this 指向,第二个参数是一个数组(只能有俩个参数) 数组里面每一项依次是给函数传递参数) 会直接把函数给调用

let a = 10;
function fn(a,b) {
    console.log(this);
    console.log(a);
    console.log(b);
}
fn.apply(a,["bb","cc"]); // 直接调用
// Number(10)
// bb
// cc

使用apply需要注意:

  • 第一个参数就是对象(你想要this指向的那个对象)
  • 第二个参数只能为数组,相当于原来函数实参(数组)
fun.apply(obj1,[n1,n2])
n1和n2为fun函数的实参
  • apply方法使用之后或自动执行该函数

四、使用bind改变this指向

语法: let aa = 函数名.bind(obj) 语法: 函数名.bind(你要改变的函数的 this 指向) 不会立即执行函数 返回值: 就是一个函数(只不过是一个被改变好了 this 指向的函数) 他对函数的参数传递有两个方式

  1. 调用返回的函数的时候传递
  2. 直接从第二个参数开始依次传递

let a = 10;
function fn(b,c) {
    console.log(this);
    console.log(b);
    console.log(c);
}
var fn1 = fn.bind(a,"bb","cc");  //返回的是改好指向的函数 并没有调用
fn();  //  window   原来函数的指向是不会改变的
fn1();   //Number {10}  

使用bind需要注意:

  • 只有一个参数对象(你想要this指向的那个对象)
  • 不会直接执行 fun 函数
  • 返回值:一个改变this指向的新函数
  • fun 函数的实参:返回新的函数的实参就是 fun 的实参

五、return改变this指向

在构造函数的时候,使用return进行返回一个object的时候,当去new一个实例对象的时候,会将this指向改变为return的object

function fn() {
    this.test = '111'
    return {
        'test':'222'
    }
}
var a = new fn;
console.log(a.test) // 222

六、 使用两个冒号改变this指向(::)

函数绑定运算符是并排的两个冒号(::),双冒号左边是一个对象,右边是一个函数。该运算符会自动将左边的对象,作为上下文环境(即 this 对象),绑定到右边的函数上面。

fn::a 等同于 a.bind(fn)
fn::a(...b) 等同于 a.apply(a,b)

var a = obj::obj.fn  等同于  var a = ::obj.fn

let b = ::console.log  等同于 let b = console.log.bind(console)