zoukankan      html  css  js  c++  java
  • js之数据类型(对象类型——构造器对象——函数1)

      函数它只定义一次,但可以被多次的执行和调用。JavaScript函数是参数化的,函数的定义会包括形参和实参。形参相当于函数中定义的变量,实参是在运行函数调用时传入的参数。

      一、函数定义

        函数使用function关键字来定义。它可以用在函数定义表达式或者函数声明语句里。    

        1、函数声明语句

        使用function关键字,后跟一组参数及函数体。

        funcname是要声明的函数名称标识符。函数名称是函数声明语句必需的部分。

        圆括号其中可以包含由0个或者是多个用逗号隔开的标识符组成的列表,这些标识符是函数的参数名称,它们就像是函数体中的局部变量一样。

        花括号,包偏一条或者是多条javascript语句。这些语句构成函数体,一旦调用函数,就会执行这些语句。

        变量的重复声明是无用的,但是函数的重复声明会覆盖前面的声明(无论是变量还是函数声明)

        <!-- <script>
            语法:
            function funcname() {
                statement;
            } 
            调用:
            1、funcname(参数);
            2、把函数声明变成函数表达式在后面加上一对小括号
        </script> -->

        2、函数表达式

         以表达式的方式来定义函数,函数的名称是可选的。

         匿名函数是function关键字后面没有标识符的函数。通常而言,以表达式方式定义函数时都是不需要名称的,这样做的好处是让代码更加简洁。函数定义表达式特别适合用来定义那些只会使用一次的函数。

       <!-- <script>
            语法:
            let functionName = function (参数) {
                statement;
            }
         let functionName = function funcName(){
           statement;
         } 调用: 1、变量(参数); 2、直接在后面加上小括号 注意:函数表达式里的function后面如果有名字的话,在调用的时候不能用这个名字去调用 </script>
    -->

        3、Function构造函数

        Function构造函数接收任意数据的参数,但最后一个参数始终都被看成是函数体,前面的参数则枚举出了新函数的参数。Function构造函数无法指定函数名称,它创建了一个匿名函数。不推荐使用。会导致两次代码的解析。

        <!-- <script>
            语法:
            var functionName=new function(){
                statement;
            }
        </script> -->

       二、函数参数 

         从函数外向函数内传入数据,在函数内可以接受到这些数据且能够使用它,这些数据就叫做参数。由于js是弱语言类型,所以js函数的参数与大多数其它语言参数有所不同,函数不介意传递进来的参数是什么类型,甚至是可以不传参。

         参数放在小括号内,可以放0个或者是多个,用逗号隔开。

         参数分为形参和实参。形参是形式上的参数,在函数声明的小括号里,形参实际上是由实参来决定的。在非严格模式下,函数中可以出现同名的形参且只能访问最后出现的该名称的形参。但在严格模式下会报错。

         实参是实际上的参数,放在了函数调用的小括号里,实参须与形参一一对应,在调用函数的时候,要把实参传够数量,如果有一个实参没有传,那它就是undefined。常常用逻辑或运算符给省略的参数设置一个合理的默认值

          js中的参数在内部用一个数组表示。函数接收到的始终都是这个数组,而不关心数组中包含哪些参数。在函数体内可以通过arguments对象来访问这个参数数组,从而获取传递给函数的每一个参数.

          arguments对象:代表了所有实参的集合,它是一个类数组。这个集合中的每个数据都有一个自己对应的下标,集合中还有一个length,代表了实参的个数(函数的length属性显示形参的个数)它只能在函数内使用,在函数外是用不了的,如果函数外使用,会报错。arguments对象中的值永远与对应命名参数的值保持同步,arguments对象与命名参数并不是访问相同的内存空间,它们的内存空间独立,但是值相等。

         ECMAScript中所有函数的参数都是按值传递的。换句话说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样。

        <script>
            function person(name, age) {
                //形参实际上就是在函数里声明的变量,变量的初始值是undefined.在函数调用时,把实参传入进来,变成真实的值
                console.log(name, age); //davina 20
            }
            person('davina', 20);
    
            function add(x, x) {
                return x;
            }
            console.log(add(1, 2)); //2
    
            /* function add(x,x){
                 'use strict'
                 return x;
             }
             cosole.log(add(1,2));  //报错 */
    
            function fn(x, y) {
                console.log(x, y);  //1 undefined
            }
            fn(1);
    
            function add(x, y) {
    
                console.log(arguments[0], arguments[1], arguments[2], arguments.length);  //1 2 3 3
                return x + 1;
            }
            add(1, 2, 3);
            console.log(add.length);//2
        </script>
        <script>
            //传递一个基本类型值时,被传递的值会被赋给一个局部变量
            function add(num) {
                num += 10;
                return num;
            }
            let count = 10;
            let re = add(count);
            console.log(re, count);//20 10
            //变量作为参数传递给函数,在函数内部,参数num被加10,这一变化不会影响函数外面的值。
    
            //向参数传递引用类型值时
            function fn(obj) {
                obj.name = 'davina';
            }
            let person = new Object();
            fn(person);
            console.log(person.name); //davina
        //函数外部创建一个对象person,然后用fn来进行调用,person的值复制一份后传递给参数obj,使得obj的引用与person指向同一对象
        </script>

      三、函数调用

        只有函数被调用时才会执行,调用运算符是跟在任何一个函数值的表达式后的一对圆括号。圆括号内可以包括多个用逗号隔开的表达式,每个表达式产生一个参数值,每个参数值被赋予函数声明时定义的形参名。js的函数调用会出现两个额外的参数,arguments和this.argument是参数组,它并不是一个真实的数组但还是可以通过.lenght方法获得长度。函数调用分为以下4种:

        1、函数调用模式(函数名(参数 ))

          当一个函数并非一个对象的属性时,那么它就是被当做一个函数来调用的,对于普通的函数调用来说,函数的返回值就是调用表达式的值。

        <script>
            let add = function (a, b) {
                // 'use strict';
                // console.log(this); //undefined
    
                alert(this);//Window
                
                return a + b;
            }
            let sum = add(3, 4);//7;
            console.log(sum);
        </script>

        使用函数调用模式调用函数时,在非严格模式下,this指向window,在严格模式下this指向undefined。

        2、方法调用模式  ( 对象.方法(参数) )

        当一个函数被保存为对象的一个属性时,我们称它为一个方法,当一个方法被调用时,this被绑定到该对象。如果调用表达式包含一个提取属性的动作,那么它就是被当做一个方法来调用。(简而言之方法调用就是用对象的方法调用,所以说方法对象一定要有宿主对象)。

        方法可以使用this访问自己所属的对象,所以它能从对象中取值或对对象进行修改,this到对象的绑定发生在调用的时候。通过this可取得它们所属对象的上下文的方法称之为公共方法。

        任何函数只要作为方法调用都会传入一个隐匿的实参,这个实参是一个对象,方法调用的母体就是这个对象。

        和变量不同,关键字this没有作用域的限制,嵌套的函数不会从调用它的函数中继承this,如果嵌套函数作为方法调用,其this的指向是调用它的对象,如果嵌套函数作为函数调用,其this的指向就是全局对象(严格模式下就是undefined)。

        所以总结来看:方法调用模式不是独立的,需要宿主,而函数调用模式是独立的

               方法调用模式方法:obj.fn(),函数调用模式方法:fn();

               方法调用模式中,this指宿主,而函数调用模式中this指全局对象

        <script>
            let myObject = {
                value: 0,
                fn1: function () {
                    console.log(this);//myObject
                    return this;
                },
                fn2: function () {
                    console.log(this);//myObject
                    this.value = 1;
                },
                fn3:function(){
                    function n(){
                        console.log(this);//window
                        return this;
                    }
                    return n();
                }
            }
    
            console.log(myObject.fn1().value);//0
    
            myObject.fn2();
            console.log(myObject.fn1().value);//1
    
            console.log(myObject.fn3());//window
        </script>

        3、构造器调用模式

          如果函数或者方法调用之前带有关键字new.那么它就构成构造函数调用。new是一个运算符,专门用来申请创建对象,创建出来的对象传递给构造函数的this,然后利用构造函数对其初始化。

          执行步骤:var p = new Person();

          如果构造函数调用在圆括号内包含一组实参列表,先计算这些实参表达式,然后传入函数内。如果构造函数没有形参,js构造函数调用的语法是允许省略实参列表和圆括号的。凡是没有形参的构造函数调用都可以省略圆括号。

          构造函数通常不使用return关键字,它们通常初始化新对象,当构造函数的函数休执行完毕时,它会显示返回,在这种情况下,构造函数调用表达式的计算结果就是这个新对象的值。

     <script>
            let o = {
                m: function () {
                    return this;
                }
            }
         let obj = new o.m(); console.log(obj, obj === o);//{} false console.log(obj.constructor === o.m);//true </script>

        4、间接调用模式

         js中函数也是对象,函数对象也可以包含方法,call(),apply()t和bind()方法可以用来间接调用函数。

         这两个方法都允许显式指定调用所需的this的值,可以修改this的指向。call()方法使用它自有的实参列表作为函数的实参,apply()方法则要求以数组的形式传入参数。

         语法:call形式:函数名.call()   apply形式:函数名.apply()    bind形式:函数名.bind()

           call()和apply()的相同点:两个方法都使用了对象本身作为第一个参数,都是用来改变this的指向。

         call()和apply()的不同点:apply()第二个参数是数组;call()第二参数是参数列表。 在js的严格模式下,在调用函数时第一个参数会成为this的值,即使该参数不是一个对象,在非严格模式下,如果第一个参数的仠是null或者是undefined,它将使用全局对象替代。

         bind() :call()改过this指向后,会再执行函数,bind()改过this后,不执行函数,会返回一个绑定新this的函数。

        <script>
            let obj = {};//定义一个空对象
            function fn(x, y) {
                console.log(this);//obj
                console.log(x, y);//1,2
            }
            fn.apply(obj, [1, 2]);
            fn.call(obj, 1, 2);//直接调用
            let b = fn.bind(obj);//bind()不能调用函数
            b();//此时才调用
        </script> 

        四、函数返回值

        函数中的return语句用来返回函数调用后的返回值,阻止函数继续运行。它经常作为函数的最后一条出现,当return被执行时,函数立即返回不再执行余下的语句。如果函数里没有return,那这个函数的返回值结果就是undefined。它只能出现在函数体内,如是不是那就会报错。一个函数中可以有多个return语句。

    <script>
        function fn(a, b) {
            return a + b;
            alert(1); //不会执行,因为放在了return后面
        }
        console.log(fn(2, 3));  //5
    
        function fn1(a, b) {
            let c = a + b;
        }
        console.log(fn1(4, 5));//undefined 函数里没有return
    </script>

      return例子:点击按钮,在按钮后方放入相加的值

        <script>
            window.onload = function () {
                let btns = document.querySelectorAll("input[type=button]");
                let texts = document.querySelectorAll("input[type=text]");
                function add() {
                    let result=0;
                    for (var i = 0; i < arguments.length; i++) {
                        result += arguments[i];
                    }
                    return result;
                }
                btns[0].onclick=function(){
                    texts[0].value=add(12,34,56,78);
    
                };
                btns[1].onclick=function(){
                    texts[1].value=add(12,56,78);
    
                }
            }
        </script>
        <input type="button" value="按钮一">
        <input type="text">
        <input type="button" value="按钮二">
        <input type="text">

     

     

      

  • 相关阅读:
    Lucene 入门实战
    ActiveMQ 入门实战(3)--SpringBoot 整合 ActiveMQ
    ActiveMQ 入门实战(2)--Java 操作 ActiveMQ
    Hdevelop(Halcon)快捷键
    2021年9月3日第7次刷第一章。但行好事莫问前程
    大家好。我准备第6次从第一章重新往回写了。
    ODOO13之十四 :Odoo 13开发之部署和维护生产实例
    Odoo 13之十三 :开发之创建网站前端功能
    ODOO13之12:Odoo 13开发之报表和服务端 QWeb
    doo 13 之11 :开发之看板视图和用户端 QWeb
  • 原文地址:https://www.cnblogs.com/davina123/p/11858857.html
Copyright © 2011-2022 走看看