JS- 函数的继承、闭包、递归、阶乘、伪数组

1- 继承

(1)借用构造函数继承成员

    <script>
        function Person(name,age){
            this.type = 'Person-我的属性'
            this.name = name
            this.age = age
        }

        Person.prototype.sayName = function(){
            console.log("我是原型的方法");
        }

        function Student(name,age){
            // 借用构造函数继承成员
            Person.call(this,name,age)
        }

        var s1 = new Student("张三",91)
        console.log(s1.type);
        console.log(s1.name);
        console.log(s1.age);
        // 继承不会继承构造函数的原型,只能继承构造函数
        console.log(s1.sayName());
    </script>

新构造函数中使用的是(需要继承的构造函数名字).call(this,继承的属性)从而继承 

  // 继承不会继承构造函数的原型,只能继承构造函数

(2)原型对象拷贝继承原型对象成员

for(var key in Person.prototype){
Student.prototype[key] = Person.prototype[key]

}

此时Student实例可以使用Person原型中的方法,继承了Person原型中的内容

(3)原型继承

Student.prototype = new Person()

 此时Student实例可以使用Person原型中的方法,继承了Person原型中的内容

2- 函数

函数声明必须有名字

函数声明:

函数声明会函数提升,在预解析阶段就已经创建,声明前后都可以调用

function foo(){

}

函数表达式:

var foo = function (){

}

函数表达式类似于变量赋值

函数表达式可以没有名字,例如匿名函数

函数表达式没有变量提升,在执行阶段创建,必须在表达式执行之后才可以调用

var foo = function(){

}

函数的调用方式:函数的调用方式决定了this指向

普通函数调用:非严格=>window,严格:undefined

构造函数调用:非严格=>实例对象,原型方法中的this也指向实例对象

对象方法调用:非严格=>该方法所属对象

 3- call、apply、bind

(1)call:

    <script>
        function fn(a,b){
            console.log(this,a,b);
        }
        fn();
        // 原来指向的是window,undefined
        // 修改了this指向就能打印1,2
        var obj = {name:123}
        fn.call(obj,1,2)
    </script>

        function fn(a,b){

            console.log(this,a,b);

        }

        fn();

打印

 

 创建一个对象并用call调用:

        var obj = {name:123}

        fn.call(obj,1,2)

 修改了this指向从window变为了对象obj

打印

 (2)apply

apply()与call()方法类似,只有一个区别,就是call()方法接收的是若干个参数的列表,而"apply()"方法接收的是数组,只能传数组

    <script>
        function fn(a, b) {
            console.log(this, a, b);
        }
        var obj = {name:"buka"}
        fn.apply(obj,[1,2])

        // apply就修改成只传接数组的形式
    </script>

 (3)bind

 4- 高阶函数

注:

        函数可以作为参数

在eat中传入函数 

        eat(function(){
            console.log("吃完了");
        })

 

        函数可以作为返回值:闭包

5- 闭包

 闭包的用途:闭包就是函数内部和外部的桥梁

可以在函数外部读取函数内部的成员

让函数内的成员始终存活在内存中

通过这样的操作可以实现:内部的匿名函数可以访问其外部的a=10

在这种情况下,内部函数可以访问并操作外部函数的变量a,并且在外部函数调用后仍然保持对a的访问权限。

6- 函数作用域、作用域链

(1)无块级作用域

    <script>
        {
            var foo = 'bar'
        }
        console.log(foo);

        if(true){
            var a = 123
        }
        console.log(a);
    </script>

(2)内层作用域可以访问外层,反之不行,比如同级函数不能调用同级函数里的变量,也就是外部不能调用内部成员

        // 作用域链
        var a = 10 
        function fn(){
            var b  = 20
                function fn1(){
                    var c = 30
                    console.log(a+b+c);
                }
                function fn2(){
                    var d = 40
                    console.log(c+d);
                }
            fn1()
            fn2()
        }
        fn()

fn2()不能访问fn1()中的成员c 

7- 函数递归

 本质上就是函数自己调用自己

    <script>
        var i = 0;
        // 函数内部调用函数本身的时候就形成了递归
        function fn(){
            i++;
            if(i>10){
                return
            }
            console.log(i);
            fn();
        }
        fn();
    </script>

 不在fn()内自调用fn(),只能打印1,调用了可以打印1到10

8- 阶乘 

    <script>
        // 阶乘
        function f(num){
            if(num<=1){
                return 1;
            }
            return num*f(num-1)
        }
        var a = f(5);
        console.log(a);
        // 1、5*f(4)
        // 2、5*4*f(3)
        // 3、5*4*3*f(2)
    </script>

return num*f(num-1)     ==>return 自己(函数本身)同时传参

9- 数组与伪数组

(1)对象与数组的关系

 对象.lengthundefined,因为其不具有数组内置的length特性

(2)伪数组

<script>
        // 数组 索引
        var arr = [1,2,3,4,5];
        arr[0];
        console.log(arr.length);

        // 对象 key (伪数组)
        var obj ={0:"a",1:"b",2:"c",length:3}
        console.log(obj[0]);
        console.log(obj.length);


        for(var i = 0;i<obj.length;i++){
            console.log(obj[i]);
        }

        // 伪数组 本质是对象
        // 伪数组 不能使用数组的api(原型中的方法)
        // 伪数组 数据类型是对象
    </script>

-->伪数组有length属性

-->伪数组也有0、1、2、3等属性对象,看起来像数组,但不是数组

不定义length就不能使用.length

常见的伪数组:

1、函数内部的arguments

2、dom对象列表

3、jQuery对象$(“div”)

伪数组是一个对象,不是数组。其存在的意义就是让普通对象也能正常使用数组的很多方法

 这里的a1没有任何作用,就是一个媒介,自始至终都是空的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值