返回顶部
首页 > 资讯 > 前端开发 > JavaScript >javascript函数的4种调用方式与this的指向
  • 808
分享到

javascript函数的4种调用方式与this的指向

摘要

目录独立调用和方法调用构造函数调用间接调用严格模式下javascript 中作用域链和 this(上下文)的指向是很容易混淆的,简单的说就是: 作用域链取决于函数声明的位置,函数声明

javascript 中作用域链和 this(上下文)的指向是很容易混淆的,简单的说就是:

  • 作用域链取决于函数声明的位置,函数声明之后,从函数内部往外,一直到window,这就是它的作用域链,与函数调用位置无关;
  • this 指向函数调用时的对象,如果是独立调用,那就是指向 window,与函数声明的位置无关;

函数调用的方式有4种,this 也就有4种指向

  • 独立调用:func(),函数独立调用,this指向window,;
  • 方法调用:obj.func(),函数作为obj的一个方法(属性)调用,this指向obj;
  • 构造函数调用:new Func(),如果在一个函数前面带上 new 关键字来调用, 那么背地里将会创建一个连接到该函数的 prototype 的新对象,this指向这个新的对象;
  • call、apply、bind调用:func.call(obj,value1,value2);  func.apply(obj,[value1,value2]); func.bind(obj,value1,value2)();  func.bind(obj)(value1,value2); 动态改变 this 的指向 obj;

独立调用和方法调用

全局环境中,this 默认指向到 window;

函数独立调用(不论这个函数在哪调用),this 默认指向到 window;

当函数被作为对象的方法(对象的一个属性)调用时,this 指向该对象;

函数只有调用了之后才有 this 的概念,不然它只是代码而已,我们经常把函数传给一个变量,如果后面没加括号,就只是传了个函数,而不是执行结果;

<script type="text/javascript">
    console.log(this === window);//true  全局环境中,this默认指向到window

    function abc(){
        console.log(this === window);
    }
    abc();//true   函数abc独立调用(不论这个函数在哪调用),this默认指向到window
    function outer(){
        function inner(){
            console.log(this === window);
        }
        inner();
    }
    outer();//true  函数inner独立调用(不论这个函数在哪调用),this默认指向到window

    var o = {
        m: function(){
            return this;
        },
        n: function(){
            function test(){
                return this;
            }
            return test(); //函数test独立调用(不论这个函数在哪调用),this默认指向到window
        }
    };
    console.log(o.m());//Object o{...}  当函数被作为对象的方法(对象的一个属性)运行时,this指向该对象
    console.log(o.n());//Window{...}  函数test独立调用,this默认指向到window
</script>

当函数被作为对象的方法调用时,可以使用 this 访问自己所属的对象,所以它能从对象中取值或对对象进行修改;

this 到对象的指向发生在调用的时候,如果函数没有被调用,则不会更改对象的变量;

通过 this 可取得它们所属对象的上下文的方法称为公共方法;

<script type="text/javascript">
    var o = {
        a: 1,
        m: function(){
            return this;
        },
        n: function(){
            this.a = 2; 
            //当函数被作为对象的方法调用时,可以使用this访问自己所属的对象,所以它能从对象中取值或对对象进行修改。
            //this到对象的绑定发生在调用的时候。所以这里的函数 n 如果没有调用过,那么外部的 a 是不会被改变的
        }
    };
    console.log(o.m().a);//1
    o.n();
    console.log(o.m().a);//2
</script>

如果想访问这个外部函数的 this 值,需要将 this 的值保存在一个变量里,内部函数就可以通过作用域链找到这个变量。

<script type="text/javascript">
    var o = {
        m: function(){
            console.log(this); //{} 当函数被作为对象的方法(对象的一个属性)运行时,this指向该对象
        },
        n: function(){
            console.log(this);//{}

            var that = this;  
            //如果想访问这个外部函数的this值,需要将this的值保存在一个变量里,内部函数就可以通过作用域链找到这个变量。

            function test(){
                console.log(this);//window
                console.log(that);//{}
            }
            return test(); //函数test独立调用(不论这个函数在哪调用),this默认指向到window
        }
    };
    o.m();
    o.n();
</script>

构造函数调用

如果一个函数用 new 关键字调用,那么这个函数就是构造函数,并且背地里会创建一个连接到该函数的 prototype 的新对象,this 指向这个新对象;

如果构造函数没有形参,实例化的时候是可以不带()的;如  var  a = Func; 或者  var a = Func(); 两种都可以;

同时我们在构造函数的时候有个约定(不是规范),首字母大写,以避免忘了写new关键字或者在普通函数前面加new;

new 关键字的作用就是执行一个构造函数,并返回一个对象实例。使用 new 命令,它后面的函数的函数调用和普通函数调用就不一样了,步骤如下:

  • 创建一个空对象,作为将要返回的对象实例;
  • 将空对象的原型 proto 指向构造函数的 prototype 属性;
  • 将构造函数内部的this关键字指向空对象;
  • 执行构造函数内部的代码;

就是说 this 指向这个新对象,构造函数内所有针对 this 的操作,都会发生在这个新对象上;

<script type="text/javascript">
    // 创建一个名为Person 的构造函数,它构造一个带有user 和age 的对象
    var Person = function (user,age) {
        this.user = user;
        this.age = age; 
    };

    // 构造一个Person 实例 ,并测试
    var shane = new Person ('shane',25);
    console.log(shane.user);//shane
    console.log(shane.age);//25
</script>

javascript 中构造函数是不需要有返回值的,可以认为构造函数和普通函数之间的区别就是:构造函数没有 return 语句,普通函数可以有 return 语句;

构造函数使用 this 关键字定义变量和方法,当 this 遇到 return 的时候,会发生指向不明(调用结果不明)的问题:

  • return 返回的不是一个对象,this 还是指向实例(新对象),调用结果也还是新对象;
  • return 返回的是一个对象,this 就指向这个返回的对象,调用结果就是这个返回的对象;
  • return 返回的是 null,this 还是指向实例,调用结果也还是新对象;
<script type="text/javascript">
    var Person = function(){
        this.user = 'shane';
        return 
    }
    var shane = new Person;
    console.log(shane.user);//shane   return没有返回值,this还是指向实例(新对象),调用结果也还是新对象;

    var Color = function(){
        this.red = 'red';
        return 'hello world';
    }
    var redColor = new Color;
    console.log(redColor.red);//red   return返回的是一个基本类型的字符串(原始值),this还是指向实例(新对象),调用结果也还是新对象;

    var Size = function(){
        this.size = 'big';
        return {};
    }
    var sizeBig = new Size;
    console.log(sizeBig.size);//undefined   return返回的是一个对象,this就指向这个返回的对象,调用结果就是这个返回的对象;
</script>

间接调用

通过 call()、apply()、bind() 方法把对象绑定到 this 上,叫做显式绑定。对于被调用的函数来说,叫做间接调用

  • call、apply、bind三者的第一个参数都是this要指向的对象,
  • bind 只是返回函数,还未调用,所以如果要执行还得在后面加个();call、apply 是立即执行函数;
  • 三者后面都可以带参数,call 后面的参数用逗号隔开,apply 后面的参数以数组的形式传入;bind则可以在指定对象的时候传参,和 call 一样,以逗号隔开,也可以在执行的时候传参,写到后面的括号中;func.call(obj,value1,value2);  func.apply(obj,[value1,value2]); func.bind(obj,value1,value2)();  func.bind(obj)(value1,value2);
<script type="text/javascript">
    var add = function (a,b) {
        return a+b;
    }; 

    var arr = [2,3];

    var sum0 = add.apply(null, arr);//apply后面的参数以数组的形式传入
    var sum1 = add.call(null,arr[0],arr[1]);//call后面的参数用逗号隔开
    var sum2 = add.bind(null,arr[0],arr[1]);//bind后面的参数可以和call一样,用逗号隔开
    var sum3 = add.bind(null); //bind调用的时候也可以在执行的时候传参

    console.log(sum0);//5
    console.log(sum1);//5
    console.log(sum2);//function (a,b) {return a+b;};    bind只是返回函数,还未调用,
    console.log(sum2());//5   所以bind调用的时候,如果要执行还得在后面加个()
    console.log(sum3(arr[0],arr[1]));//5   bind调用的时候也可以在执行的时候传参
</script>

严格模式下

  • 在严格模式下,未指定环境对象而调用函数,则 this 值不会转型为 window。 除非明确把函数添加到某个对象或者调用 apply() 或 call(),否则 this 值将是 undefined;
  • 所以我们可以手动添加 window.函数(),将 this 指向 window;
<script type="text/javascript">
    'use strict' //严格模式
    function a(){
        console.log (this);  
    }
    a();//undefined
    //在严格模式下,未指定环境对象而调用函数,则 this 值不会转型为 window , this 值将是 undefined。 
    //除非明确把函数添加到某个对象或者调用 apply()或 call()使用对象冒充。

    window.a();//window
    //所以我们可以手动添加 window.函数(),来改变this指向window

    (function(){
        console.log(this);//undefined
    })();

    setTimeout(function(){
        console.log(this);//Window
    },0);
    //setTimeout是window的一个方法(属性),所以这里可以写成window.setTimeout
//所以不管是严格模式还是非严格模式,setTimeout里的this始终指向window
//但是有时候我们会发现setTimeout中的this也有其他情况,这只是误导,当然如果你不确定的话,直接console.log(this)一下,分分钟解决
</script>

以上就是javascript函数的4种调用方式与this的指向的详细内容,更多关于javascript函数调用与this指向的资料请关注编程网其它相关文章!

--结束END--

本文标题: javascript函数的4种调用方式与this的指向

本文链接: https://lsjlt.com/news/212642.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • javascript函数的4种调用方式与this的指向
    目录独立调用和方法调用构造函数调用间接调用严格模式下javascript 中作用域链和 this(上下文)的指向是很容易混淆的,简单的说就是: 作用域链取决于函数声明的位置,函数声明...
    99+
    2023-05-19
    javascript函数调用方式 javascript函数调用 javascript this指向 javascript this
  • JavaScript类、函数和this指向怎么使用
    这篇文章主要介绍了JavaScript类、函数和this指向怎么使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇JavaScript类、函数和this指向怎么使用文章都会有所收获,下面我们一起来看看吧。1.c...
    99+
    2023-07-04
  • JavaScript创建对象的几种方式及关于this指向问题
    目录工厂模式构造函数模式关于 this原型模式工厂模式 工厂模式一般用于抽象创建特定对象的过程,是按照特定接口创建对象的方式。 function createPerson(...
    99+
    2024-04-02
  • js对象合并的4种方式与数组合并的4种方式
    目录一、对象合并1、拓展运算符(...)2、Object.assign()3、递归赋值4、jquery中的extend()二、数组合并1、扩展操作符2、使用array.conca&#...
    99+
    2022-11-13
    js对象合并 js数组合并 对象与数组合并
  • Javascript中函数分类&this指向的实例详解
    JS中定义函数的三种方式 通过实例来说明吧 <script> //method1 function fn() { ...
    99+
    2024-04-02
  • JavaScript进阶教程之函数的定义、调用及this指向问题详解
    目录前言一:函数的定义 1.1 命名函数 1.2 匿名函数 1.3 利用 new Function() 声明函数1.4 重要结论&n...
    99+
    2024-04-02
  • 如何改变函数的this指向
    本篇内容介绍了“如何改变函数的this指向”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! 如果是函数声明...
    99+
    2024-04-02
  • javascript改变this指向的方法汇总
    目录一、this指向1、全局作用下,this指向的是window2、函数独立调用时,函数内部的this也指向window3、被嵌套的函数独立调用时,this默认指向了window4、...
    99+
    2024-04-02
  • web开发中函数调用以及this的指向的示例分析
    这篇文章主要为大家展示了“web开发中函数调用以及this的指向的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“web开发中函数调用以及this的指向的...
    99+
    2024-04-02
  • JS箭头函数的this指向分析
    本篇内容介绍了“JS箭头函数的this指向分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!箭头函数是ES6中的新增特性,他没有自己的thi...
    99+
    2023-06-25
  • JS 箭头函数的this指向详解
    箭头函数是ES6中的新增特性,他没有自己的this,其this指向从外层代码库继承。 使用箭头函数时要注意一下几点: 箭头函数不能用作构造函数,用的话会抛出一个错误 ...
    99+
    2024-04-02
  • JavaScript面向对象基础与this指向的示例分析
    这篇文章给大家分享的是有关JavaScript面向对象基础与this指向的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1 、OOP的基础问题1.1什么是面向过程和面向对...
    99+
    2024-04-02
  • PYTHON中的函数指针调用的一种方法
    class  Test:    EventMethods_Test1 = 1    EventMethods_Test2 = 2    EventMe...
    99+
    2023-01-31
    指针 函数 方法
  • JavaScript this指向绑定方式及不适用情况详解
    目录前言问题复现调用位置默认绑定隐式绑定显式绑定new 绑定不适用的情况总结前言 JavaScript 中的 this 指向问题对于 web 前端入行不深的人来说是个比较复杂的问题。...
    99+
    2023-05-15
    JavaScript this指向 JavaScript this绑定方式
  • 探索 PHP 函数调用的各种方式
    php 函数调用共有五种方式:直接调用、通过变量调用、匿名函数、函数指针和反射。通过选择最适合情况的方法,可以优化性能和提高代码简洁性。 探索 PHP 函数调用的各种方式 PHP 提供...
    99+
    2024-04-16
    php 函数调用
  • JavaScript this指向绑定方式及不适用情况是什么
    这篇文章主要讲解了“JavaScript this指向绑定方式及不适用情况是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JavaScript this指向绑定方式及...
    99+
    2023-07-06
  • javascript调用函数的方法
    这篇文章主要介绍了javascript调用函数的方法,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。方法:1、用“函数名(参数,参数)”语句调用;2、作为对象的方法调用,语法“...
    99+
    2023-06-14
  • c++中的函数调用有哪几种方式
    c++ 函数调用方式有五种:值传递、引用传递、指针传递、返回值、虚函数调用。值传递传递副本,不会影响实际参数;引用传递传递引用,修改参数会影响实际参数;指针传递传递地址,修改参数会影响实...
    99+
    2024-05-01
    c++
  • java提供的4种函数式接口
    目录1、什么是函数式接口2.java提供四种类型的函数式接口1、什么是函数式接口 函数接口是只有一个抽象方法的接口,用作 Lambda 表达式的类型。使用@FunctionalInt...
    99+
    2024-04-02
  • JavaScript函数执行上下文的this怎么调用
    今天小编给大家分享一下JavaScript函数执行上下文的this怎么调用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。Ja...
    99+
    2023-07-04
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作