首页 > 其他分享 >JS-08函数的4中调用方式详解

JS-08函数的4中调用方式详解

时间:2024-05-30 23:32:10浏览次数:10  
标签:function 调用 console 函数 08 JS 详解 call var

目录

1 函数调用方式

 2 方法调用方式

例1:声明一个对象,调用对象原型里的方法

例2:直接调用对象里的方法

例3:声明一个值为函数的变量clear,在一个对象tom里的某个属性c赋值为该变量clear,然后通过该对象tom调用这个变量c

3 构造函数调用方式

例1:有一个函数,用new 来赋值,则是赋值的构造函数

例2:函数里面返回构造函数,可以访问实例本身属性,也可访问实例构造方法prototype中的属性

例3:修改函数的默认原型,指向新原型

4 上下文调用方式

例1:上下文调用call

例2:call和apply异同

例3 :上下文调用bind

5  思考如何解决bind的浏览器兼容性问题


在`ES6之前`,函数内部的this是由该函数的调用方式决定的

函数内部的this跟大小写、书写位置无关

1 函数调用方式

函数内部的this指向window


 
  var age=18;
    var p={
        age:15,
        say:function(){
            console.log(this.age);
        }
    }
    var f1=p.say;   //f1是函数
    f1();   //函数调用-->this:window -->this.age=18

将一个对象的方法赋值给一个变量,则这个变量是一个函数

f1()调用该函数,结果为18,表明函数内部的this指向window

 2 方法调用方式

函数内部的this指向调用该方法的对象


例1:声明一个对象,调用对象原型里的方法

    function Person(){
        this.age=20;
    }
    Person.prototype.run=function(){
        console.log(this.age);
    }
    
    var p1=new Person();
    p1.run();       //打印结果:20

例2:直接调用对象里的方法

   var p2={
        height:180,
        travel:function(){
            console.log(this.height);
        }
    }
    p2.travel()     //打印结果:180

例3:声明一个值为函数的变量clear,在一个对象tom里的某个属性c赋值为该变量clear,然后通过该对象tom调用这个变量c

    var clear=function(){
        console.log(this.length);
    }
    
    var length=50;
    var tom={ c:clear,length:100 };
    tom.c();        //这里是方法调用的方式        

打印this.length 是50 还是100?
-->相当于问:this是指向window还是指向tom呢? 
-->结果为:100  
-->this:tom

结论:由于clear函数被当成tom.c()这种方法的形式来进行调用,所以函数内部的this指向调用该方法的对象:tom 

3 构造函数调用方式

通过new关键字来调用的,那么这种方式就是构造函数的构造函数的调用方式,那么函数内部的this就是该构造函数的实例 


例1:有一个函数,用new 来赋值,则是赋值的构造函数

     function fn(name){
        this.name=name;
      }
 
     var _n=new fn("小明");  //_n有个name属性,值为:小明

例2:函数里面返回构造函数,可以访问实例本身属性,也可访问实例构造方法prototype中的属性

    function jQuery(){
        var _init=jQuery.prototype.init;
        //_init就是一个构造函数
        return new _init();
    }
    jQuery.prototype={
        constructor:jQuery,
        length:100,
        init:function(){
            //this可以访问到实例本身的属性,也可以访问到init.prototype中的属性
            //这里的init.prototype并不是jQuery.prototype
            console.log(this.length);   
            //正确答案:undefined
            //100? 错误的
        }
    }

补充说明:

1.变量声明了未赋值是undefined

2.属性不存在也是undefined


例3:修改函数的默认原型,指向新原型

对象的属性查找规则

1、首先查看本身有没有length属性
2、如果本身没有该属性,那么去它的原型对象中查找
3、如果原型对象中没有,那么就去原型对象的原型对象中查找,最终一直找到根对象(Object.prototype)
4、最终都没有找到的话,我们认为该对象并没有该属性,如果获取该属性的值:undefined

    function jQuery(){
        var _init=jQuery.prototype.init;
        //_init就是一个构造函数
        return new _init();
    }
    jQuery.prototype={
        constructor:jQuery,
        length:100,
        init:function(){
            //this指向init构造函数的实例
 
            console.log(this.length);   //100   
        }
    }
    var $init=jQuery.prototype.init;
    //修改了init函数的默认原型,指向新原型
    $init.prototype=jQuery.prototype;

    jQuery();//打印出:100

4 上下文调用方式

上下文调用方式,有3种,call、apply、bind

  1.call和apply是立刻执行这个函数,并且在执行过程中绑定了this这个值

  2.bind并没有立即执行这个函数,而是创建了一个新函数,新函数绑定了this这个值


例1:上下文调用call

    function f1(){
        console.log(this);
    }
    //call方法的第一个参数决定了函数内部的this的值
    f1.call([1,3,5])
    f1.call({age:20,height:1000})
    f1.call(1)      
    f1.call("abc")
    f1.call(true);
    f1.call(null)
    f1.call(undefined);

    上述代码可以用apply完全替换

    总结:

    call方法的第一个参数:

    1、如果是一个对象类型,那么函数内部的this指向该对象

    2、如果是undefined、null,那么函数内部的this指向window

    3、如果是数字-->this:对应的Number构造函数的实例。如果输入1 输出 new Number(1)

     如果是字符串-->this:String构造函数的实例。如果输入 "abc"   --> new String("abc")

     如果是布尔值-->this:Boolean构造函数的实例。如果输入false   --> new Boolean(false)


例2:call和apply异同

   同:call和apply都可以改变函数内部的this的值

   异:传参的形式不同

    function toString(a,b,c){
        console.log(a+" "+b+" "+c);
    }
    toString.call(null,1,3,5)   //"1 3 5"
    toString.apply(null,[1,3,5])//"1 3 5"

例3 :上下文调用bind

1)   调用了setTimeout函数,它会在指定的延迟(这里是50毫秒)后执行提供的函数。但是,请注意,在JavaScript中,setTimeout的回调函数中的this并不指向调用setTimeout的对象(这里是obj),而是指向全局对象(在浏览器中通常是window

    var obj = {
        age: 18,
        run: function () {
            console.log(this);  //this:obj

            var _that = this;

            setTimeout(function () {
                //this指向window
                console.log(this.age);//undefined
                console.log(_that.age);//18
            }, 50);
        }
    }

    obj.run();


2)通过执行了bind方法,匿名函数本身并没有执行,只是改变了该函数内部的this的值,指向obj5

    var obj5 = {
        age: 18,
        run: function () {
            console.log(this);  //this:obj5

            setTimeout((function () {
                console.log(this.age);  //18
            }).bind(this), 50);  //this:obj5
        }
    }
    obj5.run();

3)bind基本用法

   执行了bind方法之后,产生了一个新函数,这个新函数里面的逻辑和原来还是一样的,唯一的不同是this指向{ seconds:100 }

    function speed(){
        console.log(this.seconds);
    }
    var speedBind = speed.bind({ seconds:100 });
    speedBind();    //100

   匿名函数.调用bind方法执行

   xxx.bind()()   一般采用这种方法


    (function eat(){
        console.log(this.seconds);
    }).bind({ seconds:360 })()  //360

4)

   var obj={
        name:"西瓜",
        drink:(function(){
            //this指向了:{ name:"橙汁" }
            console.log(this.name);
        }).bind({ name:"橙汁" })
    }
    obj.drink();    //"橙汁"

    var p10={
        height:88,
        run:function(){
            //this
            setInterval((function(){
                console.log(this.height);   //88
            }).bind(this),100)
        }
    }
    p10.run();

5  思考如何解决bind的浏览器兼容性问题

标签:function,调用,console,函数,08,JS,详解,call,var
From: https://blog.csdn.net/m0_68467925/article/details/139332956

相关文章

  • 嵌入式linux系统中framebuffer应用开发详解
    大家好,今天给大家详细分析一下,利用framebuffer进行linux应用开发的详细方法。第一:LCD屏Framebuffer基本原理LCDFramebuffer就是一块显存.在嵌入式系统中.显存是被包含在内存中。LCDFramebuffer里的若干字节〈根据驱动程序对LCD控制器的配置而定〉表示LCD屏幕中的一个像素点.......
  • 算法金 | 详解过拟合和欠拟合!性感妩媚 VS 大杀四方
    大侠幸会,在下全网同名「算法金」0基础转AI上岸,多个算法赛Top「日更万日,让更多人享受智能乐趣」今天我们来战过拟合和欠拟合,特别是令江湖侠客闻风丧胆的过拟合,简称过儿,Emmm过儿听起来有点怪怪的1.楔子机器学习模型是一种能够从数据中学习规律并进行预测的算法。......
  • 【游戏设计随笔08】茶杯头游戏中的BOSS是如何干掉你的?
    茶杯头中的boss往往体型巨大,boss攻击的本质其实是阻止玩家站桩输出,同时测试玩家的跑动,跳跃,冲刺和格挡能力。boss通过各种模式的攻击组合在一起,但是这些也是可预测的,会通过动画,音效,文字来暗示你,这称之为前摇暗示“telegraphing”,敌人的前摇时长决定了游戏难度。强力的攻击往往前摇......
  • 深度神经网络详解
    一、引言随着人工智能和机器学习的发展,深度神经网络(DeepNeuralNetworks,DNNs)已经成为解决许多复杂问题的关键技术。从图像识别到自然语言处理,深度神经网络在各个领域的应用都取得了显著的成果。本篇博客将详细介绍深度神经网络的基本概念、结构、训练过程以及一些常见的应用......
  • 防止浏览器缓存了静态的配置等文件(例如外部的config.js 等文件)
    防止浏览器缓存了静态的配置文件前言1、在script引入的时候添加随机数1.1、引入js文件1.2、引入css文件2、通过html文件的<meta>设置防止缓存3、使用HTTP响应头:前言在实际开发中浏览器的缓存问题一直是一个很让人头疼的问题,尤其是我们打包时候防止的静态配置文件con......
  • 代码随想录算法训练营第第23天 | 669. 修剪二叉搜索树、108.将有序数组转换为二叉搜索
    修剪二叉搜索树这道题目比较难,比添加增加和删除节点难的多,建议先看视频理解。题目链接/文章讲解:https://programmercarl.com/0669.修剪二叉搜索树.html视频讲解:https://www.bilibili.com/video/BV17P41177ud/***@param{TreeNode}root*@param{number}low*@pa......
  • [JSOI2015] 染色问题
    [JSOI2015]染色问题题目描述萌萌家有一个棋盘,这个棋盘是一个\(n\timesm\)的矩形,分成\(n\)行\(m\)列共\(n\timesm\)个小方格。现在萌萌和南南有\(C\)种不同颜色的颜料,他们希望把棋盘用这些颜料染色,并满足以下规定:棋盘的每一个小方格既可以染色(染成\(C\)种颜......
  • 模型节点操作学习笔记(1)--SavedModel详解
    参考:使用SavedModel格式 | TensorFlowCore(google.cn) (持续更新)   SavedModel是一个包含序列化签名和运行这些签名所需的状态的目录,其中包含变量值和词汇表。$ls{mobilenet_save_path}assetsfingerprint.pbsaved_model.pbvariablesassets目......
  • JSON 文件操作:Python 中最好的 JSON 数据持久化工具
    ......
  • Milvus向量数据库详解
    Milvus向量数据库是一款专为向量查询与检索设计的云原生数据库,它具备高性能、高可用、易拓展的特点,主要用于处理由深度神经网络和其他机器学习模型生成的Embedding向量。以下是关于Milvus向量数据库的详细说明:定义与用途:Milvus是一款云原生向量数据库,专为处理海量向量数据......