JS 中的this指向问题和call、apply、bind的区别

Stella981
• 阅读 433

this的指向问题

  • 一般情况下this对象指向调用函数的对象,全局环境中执行函数this对象指向window。

    function a(){
    console.log(this); //输出函数a中的this对象 } function b(){}; var c={name:"call"}; //定义对象c
    var c = { getFunc:function(){ return function(){ console.log(this) } } } var cFun = c.getFunc(); cFun()//Window 这是因为在全局环境下执行的函数

  • 在call和apply函数中this指向的是指定的对象,如果指定的对象为undefined或者null,那this对象指向window,如果指定的对象为空this也是指向的window,如果指向的对象是字符串,那this指向的就是String

    var d = { getThis:function(){ console.log(this) } } var e = { name:'e'//(给e写个name属性只是因为觉得孤零零的太难看了~~) } d.getThis.call(e); //这句话就相当于说把对象d中的上下文环境换成了对象e d.getThis.call(66); //Number d.getThis.call('wan'); //String d.getThis.call(); //Window d.getThis.call(true); //Boolean

  • 如果在箭头函数中,this对象等同于外层代码中的this

    var f = { getThis: ()=>{ console.log(this) }, getThis2: function(){ console.log(this); } } f.getThis(); //Window f.getThis2(); //f

call、apply、bind的区别

  • call的基本用法

    • 语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]])
    • 定义:调用一个对象的一个方法,以另一个对象替换当前对象。
    • call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
    • thisObj的取值有以下4种情况:
      • 不传,或者传null,undefined, 函数中的this指向window对象
      • 传递另一个函数的函数名,函数中的this指向这个函数的引用
      • 传递字符串、数值或布尔类型等基础类型,函数中的this指向其对应的包装对象,如 String、Number、Boolean
      • 传递一个对象,函数中的this指向这个对象

    function a(){
    console.log(this); //输出函数a中的this对象 }
    function b(){}
    var c={name:"call"}; //定义对象c
    a.call(); //window a.call(null); //window a.call(undefined); //window a.call(1); //Number a.call(''); //String a.call(true); //Boolean a.call(b); //function b(){} a.call(c); //Object

  • apply的基本用法

    • 语法:**apply([thisObj[,argArray]]) **
    • 定义:应用某一对象的一个方法,用另一个对象替换当前对象。
    • 如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。 如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。

    function class1(args1,args2){
    this.name=function(){
    console.log(args,args);
    }
    }
    function class2(){
    var args1="1"; var args2="2"; class1.call(this,args1,args2);
    // class1.apply(this,[args1,args2]); } var c=new class2();
    c.name(); //1,2

  • bind的基本用法

    • bind是在EcmaScript5中扩展的方法(IE6,7,8不支持)

    • bind() 方法与 apply 和 call 很相似,也是可以改变函数体内 this 的指向。

    • bind()方法会创建一个新函数,称为绑定函数,当调用这个绑定函数时,绑定函数会以创建它时传入 bind()方法的第一个参数作为 this,传入 bind() 方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数

      var bar = function(){ console.log(this.x); } var foo = { x:3 } bar(); // undefined var func = bar.bind(foo); func(); // 3

  • call、apply、bind三者的区别

    • 三者都是来改变函数的this对象的指向的

    • 三者的第一个参数都是this要指向的对象,也就是要指定的上下文

    • 三者都可以利用后续参数传参

    • bind是返回对应函数,便于稍后调用,call、apply是立即调用

    • call和apply作用是完全一样的,只是接收参数的方式不一样,call需要把参数按顺序传递进去,而apply则是把参数放在数组里。

      var obj = { x: 81, }; var foo = { getX: function() { return this.x; } } console.log(foo.getX.bind(obj)()); //81 console.log(foo.getX.call(obj)); //81 console.log(foo.getX.apply(obj)); //81 三个输出的都是81,但是注意看使用 bind() 方法的,他后面多了对括号。

参考文章:https://www.cnblogs.com/libin-1/p/6069031.html

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
2年前
java 复制Map对象(深拷贝与浅拷贝)
java复制Map对象(深拷贝与浅拷贝)CreationTime2018年6月4日10点00分Author:Marydon1.深拷贝与浅拷贝  浅拷贝:只复制对象的引用,两个引用仍然指向同一个对象
Dax Dax
2年前
JavaScript中call()、apply()、bind()的用法
call()apply()bind()都是用来更改this的指向的其中bind()返回的是一个函数,必须执行才行传参差异:call、bind、apply这三个函数的第一个参数都是this的指向对象,第二个参数差别就来了:call的参数是直接放进去的,第二第三第n个参数全都用逗号分隔,直接放到后面obj.myFun.call(db,'
巴拉米 巴拉米
3年前
bind、call、apply 区别?如何实现一个bind?
一、作用call、apply、bind作用是改变函数执行时的上下文,简而言之就是改变函数运行时的this指向那么什么情况下需要改变this的指向呢?下面举个例子var name"lucy";const obj{    name:"martin",    say:function (){        co
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
JS 对象数组Array 根据对象object key的值排序sort,很风骚哦
有个js对象数组varary\{id:1,name:"b"},{id:2,name:"b"}\需求是根据name或者id的值来排序,这里有个风骚的函数函数定义:function keysrt(key,desc) {  return function(a,b){    return desc ? ~~(ak
Wesley13 Wesley13
2年前
Java 多态
类型的检测——向上转型向下转型向上转型:父类对象的引用指向子类对象,向下转型:向上转型的基础上再次指向子类的对象1.向上转型!(https://oscimg.oschina.net/oscnet/dd0d05d39a724e781b799ff5e35b921775d.jpg)!(https://oscimg.oschina.net/o
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Python进阶者 Python进阶者
2个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这