JS中this关键字转变指向的三种要领(apply、call、bind)

起首,相识一下this关键字。this关键字就涉及到函数挪用的内容。函数的几种挪用体式格局:

1 一般函数挪用
2 作为要领来挪用
3 作为组织函数来挪用
4 运用apply/call要领来挪用
5 Function.prototype.bind要领
6 ES6箭头函数

然则不论函数是按哪一种要领来挪用的,都须要记着一点:谁挪用这个函数或要领,this关键字就指向谁。

一般函数挪用

var age = 18;
function person(){
    this.name = "Tony";
    console.log(this);      //window
    console.log(this.name); //Tony
    console.log(this.age);  //18
}
person();

代码中定义一个一般函数person,在挪用时实际上person是作为全局对象window的一个要领来举行挪用的,即window.person();
因此是window对象挪用了person要领,那末person函数当中的this即指window,同时window还具有了别的一个属性name,值为“Tony”。

定义一个全局变量age,它相称因而window的一个属性。在挪用person函数时它的this指向window,所以在函数内部能够接见到age变量,这也诠释了函数内部可接见全局变量。

作为要领来挪用

var person = {
    name : "Tony",
    showName:function(){
        console.log(this.name);
    }
}
person.showName();

var name = "Tom";
var showname = person.showName;
showname();

定义一个对象person包括一个showName的要领,在对象person内挪用要领返回的是Tony,明显this指向了对象person。

再定义一个全局变量name,将person.showName要领赋值给变量showname,由于在全局定义的嘛,所以showname也相称于window的一个属性,此时挪用showname它的this是指向window的,所以返回的值就是全局变量“Tom”。

var personA = {
    name : "Tony",
    showName:function(){
        console.log(this.name);
    }
}
var personB = {
    name : "Tom",
    sayName:personA.showName
}
personB.sayName();    //Tom

personB对象中的要领挪用personA中的要领,虽然showName是personA中定义的,但挪用了personB,那this就指向了personB。

作为组织函数来挪用

function Person(name){
    this.name = name;
}
var personA = new Person("Tony");
console.log(personA.name);

组织函数new出来的实例,this指向这个实例对象。

下面就来相识一下this指向转变的三种要领。

在JavaScript中,call、apply和bind是Function对象自带的三个要领,这三个要领的重要作用是转变函数中的this指向。所以可知它们的共同点就是都用来转变函数的this对象的指向的;另有就是三者第一个参数都是this要指向的对象,也就是想指定的上下文(函数的每次挪用都邑具有一个特别值——本次挪用的上下文(context)——这就是this关键字的值。),然后再利用后续参数传参。而它们的差别也就是传参的差别,bind 是返回对应函数,便于稍后挪用;apply 、call 则是马上挪用 。

apply()要领 

它吸收两个参数,一个是函数运转的作用域(this),另一个是参数数组。

语法:

apply([thisObj [,argArray] ]);

定义:运用某一对象的一个要领,用另一个对象替换当前对象

申明:假如argArray不是一个有用数组或不是arguments对象,那末将致使一个 TypeError,假如没有供应argArray和thisObj任何一个参数,那末Global对象将用作thisObj。

function Person(name){
    this.name = name;
    this.showName = function(){
        console.log(this.name);
    }
}
function Student(name){
    Person.apply(this,arguments);
}
var stu = new Student("Tony");
stu.showName();

call()要领 

它第一个参数和apply()要领的一样,然则通报给函数的参数必需枚举出来。

语法:

call([thisObject[,arg1 [,arg2 [,...,argn]]]]);

定义:挪用一个对象的一个要领,以另一个对象替换当前对象。

申明: call要领能够用来替换另一个对象挪用一个要领,call要领能够将一个函数的对象上下文从初始的上下文转变成thisObj指定的新对象。

thisObj取值的状况:

1 不传,或许传null,undefined, 函数中的this指向window对象
2 通报另一个函数的函数名,函数中的this指向这个函数的援用
3 通报字符串、数值或布尔范例等基本范例,函数中的this指向其对应的包装对象,如 String、Number、Boolean
4 通报一个对象,函数中的this指向这个对象

call要领的一些罕见例子:

1.

function add(a,b){
    console.log(a+b);
}
function subtraction(a,b){
    console.log(a-b);
}
add.call(subtraction,3,1);    //4

定义一个加法函数、加法函数,末了的挪用语句意义就是用加法替换了减法,在减法函数中经由过程call要领转变了this的指向,已不再盘算a-b,而是作用加法中的a+b。

2.

function Student(){
    this.name = "Tom";
    this.showName = function(){
        console.log(this.name);
    }
}
function Teacher(){
    this.name = "Tony";
}
var stu = new Student();
var tea = new Teacher();
stu.showName.call(tea);

定义一个门生函数,它有属性name和要领showName,而先生函数只要name属性,末了一个挪用语句的意义就是把门生的要领用到了先生函数中实行,即使先生是没有这个要领的。

3.

function Parent(name){
    this.name = name;
    this.showName = function(){
        console.log(this.name);
    }
}
function Son(name){
    Parent.call(this,name);
}
var baby = new Son("Tony");
baby.showName();

Parent.call(this,name)意义就是运用父母这个对象替换掉儿子函数中的this对象,那末这个儿子函数中就能够直接挪用父母对象中的属性和要领,这也就是继续。

bind()要领

bind()最简朴的用法是建立一个函数,使这个函数不论怎么挪用都有一样的this值。

var person = {
    name : "Tony",
    showName : function(){
        console.log(this.name);
    }
}
person.showName();      //Tony

var name = "Tom";
var getName = person.showName;
getName();              //Tom

var boundGetName = getName.bind(person);
boundGetName();         //Tony

    原文作者:bertZuo
    原文地址: https://segmentfault.com/a/1190000019234445
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞