前端学习笔记JavaScript - 函数

函数

函数和方法的区别

什么是函数

没有和其他的类绑定在一起的称为函数

        function test() {
            console.log("你好呀");
        }
        test();

什么是方法

和其他类绑定再一起的称为方法

        let test = {
            say:function () {
                console.log("你好呀");
            }
        }
       
       test.say();

函数和方法的区别

  • 函数可以直接调用,方法只能通过对象调用。
  • 函数内部this是window,方法内部this是调用的那个对象。

arguments

保存所有传递函数的实参

      function sum() {
            let sum2 = 0;
            for (let i = 0;i < arguments.length;i++){
                sum2 += arguments[i];
            }
            return sum2;
        }

       console.log(sum(1,2,3,4));

扩展运算符

1.扩展运算符在等号的左边,会将剩余的数据打包到一个数组中。

注意:扩展运算符只能写在最后

        let [a,...b] = [1,2,3];
       console.log(a,b);

2.扩展运算符在等号的右边,会将数组中的数据解开(解构)

			 let arr1 = [1,2,3];
       let arr2 = [4,5,6];
       let arr3 = [...arr1,...arr2];
       console.log(arr3);

3.扩展运算符在函数的形参列表中的作用,将传递的函数实参打包到一个数组中

注意:扩展运算符只能写在最后一个形参上

        function getSum(...numList) {
            console.log(numList);
            let sum = 0;
            for (let i = 0;i < numList.length; i++){
                sum += numList[i];
            }
            return sum;
        }

        let sum1 = getSum(1,2,3)

       console.log(sum1);

参数

形参:定义函数时()中的参数叫形参

实参:调用函数时()中传入的参数叫实参

形参默认值

没有设置默认值时,形参的默认值就是undefined

ES6后设置默认值

可以直接设置默认值,也可以通过方法传递默认值

				function setStr() {
            return "哈1哈";
       }

        function getStr(a = "你好",b = setStr()) {
            console.log(a,b);
        }

        getStr();

函数作为参数返回值

函数可以作为其他函数的参数

				let say = function () {
            console.log("哈哈哈");
        }

        function test(fn) {
            fn();
        }

        test(say);

函数可以作为其他函数的返回值

        function test() {
            let ha = function () {
                console.log("哈哈哈")

            }
            return ha;
        }

        let fn = test()
        fn();

匿名函数

有名称的函数

				let say = function () {
            console.log("哈哈哈");
        }
				let ha = function () {
             console.log("哈哈哈")
            }

没有名称的函数 - 匿名函数

注意点:

  • 匿名函数不能只定义不使用

使用场景

  • 作为其他函数的参数
        function say(fn) {
            fn();
        }

        say(function () {
            console.log("哈哈")
        });
  • 作为其他函数的返回值
        function say() {
            return function () {
                console.log("哈哈哈1")
            }
        }

        let fn = say();
        fn();
  • 作为一个立即执行的函数
       (function () {
            console.log("哈哈哈");
        })()

箭头函数

为了简化定义函数的代码

ES6之前定义函数

function 函数名称(形参列表){
		需要封装的代码
}

let 函数名称 = function(形参列表){
		需要封装的代码
}

ES6开始定义函数

 let 函数名称 = (形参列表)=>{
 		 需要封装的代码
 }

注意点

  • 如果函数只有一个形参,那么()可以省略,如果{}中只有一句代码,{}可以省略
       let test = name => console.log(name);
       test("哈哈");

递归函数

在函数中自己调用自己 - 递归函数

        function test() {
            let pas = prompt("请输入密码");
            if (pas !== "123456"){
                test();
            }
            alert("欢迎回家")
        }
        test();

工厂函数

专门用于创建对象的函数

    function test(myname) {
        let obj = {}
        obj.name = myname;
        obj.age = 12;
        obj.say = function () {
            console.log(obj.name+"你好,我今年"+obj.age+"岁");
        }

        return obj;
    }

    let myobj = test("zs");
   myobj.say();

构造函数

用于创造对象的函数-工厂函数的简写

注意点

  • 首字母必须大写
  • 只能通过new来调用
        function People(myName) {
            this.name = myName;
            this.age = 12;
            this.say = function () {
                console.log(this.name+"你好,我今年"+this.age+"岁");
            }
        }

        let obj = new People ("zs");
        obj.say();

prototype

每个构造函数中都有一个默认的属性,叫做prototype

应用场景

prototype中一般存储的是所有对象都相同的一些属性和方法,如果是对象特有的属性或方法,我们会存储到构造函数中

特点

  • 可以存储方法 - 存储再prototype中的方法可以被对应的构造函数创建出来的对象共享。
  • 可以存储属性
  • 如果prototype中的出现了和构造函数中同名的属性或方法,那将会访问构造函数中的属性和方法。
       People.prototype = {
            // -- 防止破坏原有关系,需要手动指定constructor指向谁
            constructor:People;
           type:"人",
           say:function () {
               console.log("我们都会说话");
           }
        }

        function People(myName,myAge) {
            this.name = myName;
            this.age  = myAge;
        }
       
        let xiaoMing = new People("小明","15");
        console.log(xiaoMing.type);
        xiaoMing.say();
  • 注意:再给一个对象不存在的属性设置值的时候,不会去原型对象中寻找,如果当前对象没有这个值就会给当前对象新增一个不存在的值。

函数中变量的作用域

  • {}外面的作用域 - 全局作用域
  • 函数后面{}的作用域 - 局部作用域
  • {}没有和函数结合在一起 - 块级作用域

在块级作用域中通过var定义的变量都是全局变量

在局部作用域中通过var定义的变量都是局部变量

  • 省略变量前面的let或者var无论在哪里都是全局变量

创建对象

通过系统的Object类创建对象

			 let test = new Object();
        // let test = {};
        test.name = "哈哈";
        test.age = 12;
        test.say = function () {
            console.log("hello word");
        }
       console.log(test.name);
       console.log(test.age);
       test.say();

        let test = {
            name:"哈哈",
            age:12,
            say:function () {
                console.log("你好呀");
            }
        }

       console.log(test.name);
       console.log(test.age);
       test.say();

对象三角恋

  • 每个"构造函数"中都有一个默认的属性,叫做prototype,prototype属性保存着一个对象,这个对象叫"原型对象"

(原型的概念:每一个JavaScript对象(null除外)创建时,就会关联另一个对象,这个对象就是原型对象)

  • 通过"构造函数"创建出来的对象为"实例对象",每个"实例对象"中都有一个默认的属性,叫做"__proto__","__proto__"指向创建它的那个"构造函数"的"原型对象"

  • 每个"原型对象"中都有一个默认的属性,叫做constructor,constructor指向当前原型对象对应的"构造函数"

Function函数

  • javaScript中函数是引用类型(对象),既然是对象,所以也是通过构造函数创建出来,所有函数都是通过Function构造函数创建出来的对象。
  • Function的"__proto__"指向Function的"原型对象"

Object函数

函数对象完整关系图

  • Function函数是所有函数的祖先函数
  • 所有构造函数都有一个prototype属性
  • 所有的原型对象都有一个constructor 属性
  • 所有的函数都是对象
  • 所有的对象都有一个__proto__属性

原型链

posted @ 2020-08-13 14:50  cmg123  阅读(139)  评论(0)    收藏  举报