zoukankan      html  css  js  c++  java
  • javascript中call与this的初见

    call定义

    语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]]) 
    定义:调用一个对象的一个方法,以另一个对象替换当前对象。 
    说明:call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。 
    如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。

    又遇见了各种专业名词了吧,没有经过长期的文档摧残是无法快速掌握一个方法的精髓的,一起做几个小实验吧

    var myName = 'goudan';

    var myAge = 13;

    function showMsg(msg){

      return msg + ''.toLowerCase();

    }

    showName(myName); // 'goudan'

    这段代码很容易就能看懂,在实际开发工作中,我们会处理不同的数据集合,这时候var单一变量已经无法满足胃口,需要通过json的形式来存储数据

    var person = {

      name:"kyogre",

      age:13,

      hobby:"coding"

    }

    var newPerson  ={

      name:'dachui',

      age:99,

      hobby:'eat'

    }

    function showMsg(msg){

      return msg + ''.toLowerCase();

    }

    showMsg(person.name) // 'kyogre'

    showMsg(newPerson.name) // 'dachui'

    存储数据的方式发生了改变,但是我们处理数据的方式还是那么。。。古老,如果业务复杂一点

    function format(msg){

      return msg+''.toLowerCase();

    }

    function show(msg){

      return '信息的内容是:'+ format(msg);

    }

    show(person.name) // '信息内容是:kyogre'

    show(newPerson.name) // '信息内容是:dachui'

    显示的传递上下文对象 (穿参)使得业务越来越复杂,这种叠加会让开发变得冗余和难以解读,bug和闭包横飞

    那我们看看通过this如何清晰解决问题

    通常this不会指向函数自身,而是调用函数的对象主体。当然,我们可以强制让function自身成为对象主体,这个以后咱们讨论; json本身就是对象,我们是否可以这样:

    var person = {

      name:"kyogre",

      age:13,

      hobby:"coding"

    }

    var newPerson  ={

      name:'dachui',

      age:99,

      hobby:'eat'

    }

    function format(){

      return this.name+''.toLowerCase();

    }

    问题来了,不让穿参这个format中的this指向谁呢? 指向调用format的对象本身,可是调用主体并不明确,可能是person也可能是newPerson,这时回过头看看call的定义吧:调用一个对象的一个方法,以另一个对象替换当前对象。 将函数内部执行上下文对象由原始对象替换为指定对象

    var name = '我叫window';    //全局变量 非严格模式下都为 window的属性   window.name;

    function format(){

      return this.name+''.toLowerCase();

    }

    format(); //'我叫window';    

    不要惊慌,本身他就是这样window会作为调用顶级作用域链函数的对象主体;这里的this默认为 window, 用person对象代替window这个默认this主体去执行format会怎么样呢

    format.call(person);

    // kyogre

    format.call(newPerson);

    // dachui

    function show(){

      return '信息的内容是:'+ format.call(this);

    }

    show.call(person); // 信息的内容是:kyogre

    感觉自己了解了this和call的小明,已经肆无忌惮的笑了起来,这样他就可以从繁重的回调与参数传递中解脱了,并且能够实现方法的初级模块化。可是事情并没有这么简单。。。知道的越多,不知道的就越多 ;-)


    下面可以用call做一些平常的操作

    function isArray(object){

      return Object.prototype.toString.call(object) == '[object Array]';

    }// 借用Object原型上的toString方法来验证下对象是否是数组?

    function accumulation(){

      return [].reduce.call(arguments,(a,b)=>{return a+b}

    }//让不能使用数组方法的arguments类数组集合使用借用数组的reduce方法

    return Array.prototype.forEach.call($$('*'),(item)=>{item.style.border = '1px solid red';}

    //把类数组节点集合通过call借用数组的forEach方法实现。。。你自己在控制台用一下就知道,O(∩_∩)O~

    真正决定this指向谁的并不一定是能看的见的对象,很多情况this会被隐性改变,this没有谁调用就指向谁那么简单; 如果想要深入理解,我们下次有机会谈一下执行上下文和词法作用域吧。。。。

  • 相关阅读:
    筛选DataTable行重复
    还原数据库时在向服务器发送请求时发生传输级错误
    not in 语句 要 排除 null情况
    C#实现万年历(农历、节气、节日、星座、星宿、属相、生肖、闰年月、时辰)
    关于Form_Load和Public Form()那些事
    C#多线程编程简述(转载)
    标识列重置
    NET批量大数据插入性能分析及比较
    Asp.net 备份和还原SQL Server及压缩Access数据库
    线性查找(递归)
  • 原文地址:https://www.cnblogs.com/ifworld/p/7638408.html
Copyright © 2011-2022 走看看