this指向解读:

1.函数外面的this,即全局作用域的this指向window。

2.函数里面的this总是指向直接调用者。如果没有直接调用者,隐含的调用者是window。

3.使用new调用一个函数,这个函数即为构造函数。构造函数里面的this是和实例对象沟通的桥梁,它指向实例对象。

4.箭头函数里面的this在它申明时确定,跟他当前作用域的this一样。5.DOM事件回调里面,this指向绑定事件的对象(currentTarget),而不是触发事件的对象(target)。当然这两个可以是一样的。如果回调是箭头函数,请参考上一条,this是它申明时作用域的this。

6.严格模式下,函数里面的this指向undefined,函数外面(全局作用域)的this还是指向window。

7.call和apply可以改变this,这两个方法会立即执行原方法,他们的区别是参数形式不一样。

8.bind也可以修改this,但是它不会立即执行,而是返回一个修改了this的函数。

在JavaScript中,函数内的this指向不是一成不变的,有时我们需要改变函数内的this指向.JavaScript提供了三种方法进行改变:call()、apply()、bind();

1.call()方法

call()方法使用一个指定的this值和单独给出的一个或多个参数来设置一个函数的this指向,并调用该函数.

语法:

function.call(thisArg,arg1,arg2,...,argn);

function: 被操作函数,表示将要改变this指向的被操作函数

thisArg:可选参数,表示this指向的目标对象.如果没有传递该参数,this 的值将会被绑定为全局对象(严格模式下是undefined)。

arg1,arg2,...,argn:可选参数.表示指定的参数列表(即传递给函数的实参内容)

call() 提供新的 this 值给当前调用的函数/方法。

案例:

const child={
    name:'XiaoMing',
    age:20
}

function person(name,age){
	console.log(this);
    console.log(`我的名字是${name},今年${age}岁了.`)
}

// 直接调用person函数
person('小美',18); 
/** 
	输出结果为:
                window对象
                我的名字是小美,我今年18岁了
**/

// 通过call方法设置this并调用函数
person.call(child,child.name,child.age); 
/**
	输出结果为:
				{name:'XiaoMing',age:20} // child对象
				我的名字是XiaoMing,我今年20岁了.
**/

2.apply()方法

apply()方法使用一个指定的this值和单独给出的一个数组或类似数组的参数来设置一个函数的this指向,并调用该函数.

语法:

function.apply(thisArg,argsArray)

function:指定被操作的函数对象

thisArg:可选参数,表示this最终指向的目标对象.(若不填,则this指向全局对象.严格模式下是undefined)

案例:

let child = {
        name: '小明',
        age: 18,
      };
      function person(...item) {
        console.log(this);
        console.log(item);
      }
person.apply(child, [child.name, child.age]);
/**
	输出结果为:
			{name:'小明',age:18}
			['小明',18]
**/




let list=[1,2,3];
let list2=[4,5,6];
list.push.apply(list,list2); // list.push是一个调用函数方法的形式.
console.log(list); // [1,2,3,4,5,6] 
console.log(list2); // [4,5,6
      
 /* 找出数组中最大/小的数字 */
var numbers = [5, 6, 2, 3, 7];

/* 使用Math.min/Math.max以及apply 函数时的代码 */
var max = Math.max.apply(null, numbers); /* 基本等同于 Math.max(numbers[0], ...) 或 Math.max(5, 6, ..) */
var min = Math.min.apply(null, numbers);

/* 对比:简单循环算法 */
max = -Infinity, min = +Infinity;

for (var i = 0; i < numbers.length; i++) {
  if (numbers[i] > max)
    max = numbers[i];
  if (numbers[i] < min) 
    min = numbers[i];
}

3.bind()方法(开发常用)

bind()方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。

bind()方法只改变被操作对象的this指向,并不会调用函数.该方法返回一个新this指向的新函数.

语法:

function.bind(thisArg,arg1,arg2,...,argn)

thisArg:可选参数,表示新的this指向目标对象

arg1,arg2...:可选参数,表时绑定新this时传入的参数.

案例:

let child = {
        name: '小明',
        age: 18,
      };
      function person(...item) {
        console.log(this);
        console.log(item);
      }
      person.bind(child,'Hello','World')(); // bind()方法不会调用函数,需要手动调用.
   
/**
	输出结果为:
			{name:'小明',age:18}
			['Hello','World']
**/