JS闭包-继承

作者: 樊小勇 | 来源:发表于2019-04-24 22:06 被阅读3次
    • 形成一个闭包
      函数里面返回一个函数
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>闭包</title>
        <style>
            li{
                border: 1px solid red;
            }
        </style>
    </head>
    <body>
        <ul>
            <li>1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
            <li>5</li>
            <li>6</li>
        </ul>
        <script>
            // 为什么会有闭包,因为作用域的问题
            // 自调用()(),
            function a(){
                return function b(){
                    // 一个函数里面放回一个函数这种情况称为闭包
                    console.log('这是访问闭包里的返回函数');
                }
            }
            // 访问闭包的方法
            a()();
            // 闭包的用途,保存私有的方法和私有的数据
            // 优点:浏览器默认会清理掉没有使用的变量,可以通过闭包的方式内部调用变量来实现储存的变量和方法
            // 缺点:但是相应的会造成浏览器内存的占用,使得内容运行缓慢
            function b(){
                var b = 2;
                return function c(){
                    var sum = b + 1;
                    console.log(sum);
                }
            }
            b()();
    
            // ()() 还有个用途就是生成一个 命名空间, 可以 类似于自调用,前面的括号放我们的闭包函数
            // 后面的括号相当于调用这个闭包函数里面也可以传参数
            // 事件队列:在大量事件待执行的时候会把事件列一个队列等待调用
            var dom = document.querySelectorAll('li');
            for(let j=0;j<dom.length;j++){
                dom[j].onclick=function(){
                    console.log(j+1)
                }
            }
            // 需求:根据点击打印出点击的下标
            // let 是局部变量,而var 是全局变量,因此后者需要调用闭包来达到需求
            for(var i =0;i<dom.length;i++){
                dom[i].onclick=(
                    function(a){
                        return function(){
                            console.log(a+1)
                        }
                    }
                )(i)
            }
            // 倘若不进行闭包处理,var的变量会执行完for循环,点击时i全变成了6
    
    
    
            // 添加事件的扩展
            // DOM 事件 最常用的
            var lis = document.querySelectorAll('li')
            for(let i=0;i<lis.length;i++){
                // 参数;事件类型 事件处理函数(回调) 监听器  冒泡或者捕获(布尔值)
                lis[i].addEventListener('click',function(){
                    console.log(i);
                },false)
            }
            // 和onclick的区别,onclick会覆盖,也就是说只能同一个节点有一个
            // 而addEventListener不会覆盖
    
    
             // 伪数组 arguments 不能直接使用数组方法
            //  但是可以通过call 和 apply 上下文方法来使用
            Array.prototype.join.call('arguments',['-']);
            // 在arguments数组里的属性之间加一个 -
        </script>
    </body>
    </html>
    
    • 继承
      继承的几种方式
      1.ES6 extends
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>继承</title>
    </head>
    <body>
        <script>
            // 继承实现的原理:通过原型链 实现的继承
            //  抽象出共有的属性或者方法
    
    
            // ES6
            class People{
                constructor(name,age,skin){
                    this.name = name,
                    this.age = age,
                    this.skin = skin
                }
                eat(){
                    console.log('吃饭')
                }
                sleep(){
                    console.log('睡觉')
                }
                speak(){    
                    console.log('说话')
                }
            }
            // 继承 extends
            class Student extends People{
                constructor(name,age,skin,id,classs){
                    super(name,age,skin)
                    this.id = id,
                    this.classs=classs
                }
                study(){
                    console.log('读书')
                }
            }
            var ren = new Student('张三',14,'yellow',01,'学生')
            // 控制台可见,eat方法在对象ren的原型 的原型里
            console.log(ren.eat());
        </script>
    </body>
    </html>
    

    继承的几种方式
    1.构造函数继承
    构造函数通过call(this)继承另一个构造函数(无法继承方法或属性)
    2.原型继承
    new一个构造函数A等于另一个构造函数B的原型,然后通过new B生成一个继承对象(多对一,一个对象更改继承的函数数据就会更改)
    3.组合继承
    构造函数和原型函数一起使用,更改B的原型指向自己B

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>继承-2</title>
    </head>
    <body>
        <script>
        //    继承的几种方式
        //    1.构造函数继承--------
        /*
          问题:
            原型上的方法或者属性无法继承
        */ 
        function Fn(){
            this.name = '张三',
            this.eat = function(){
                console.log('eat');
            }
        }
        function F(){
            // call(obj,'') apply(abj,[]) 函数自带的方法 上下文 前面传参一样后面不一样
            // 使用call和apply更改this指向
            Fn.call(this)
            // 这个时候的this相当于f,于是乎Fn里的this相当于替换成了f这样便达到了继承的效果
            console.log(this);   // f
        }
    
        var fn = new Fn();
        console.log(fn);
    
        var f = new F();
        console.log(f);
    
        // 2. 原型继承
        // 问题:  公用一个原型对象,就会导致,一个修改了原型对象的值其余所有的都会被修改
        function Fun(){
            this.name = '张三',
            this.color = ["1","2"]
            this.eat = function(){
                console.log('eat');
            }
        }
        Fun.prototype.sleep=function(){
            console.log('睡觉');
        }
        function X(){
    
        }
        X.prototype = new Fun();
        var x = new X();
        // 这个就可以继承Fun的原型上的方法
        console.log(x);
        var a = new X();
        var b = new X();
        a.color.push('李四');
        console.log(b.color); // 更改a但是b的color也更改了
    
        // 3.组合方式
        function Fy(){
            this.name = '张三',
            this.color = ["1","2"]
            this.eat = function(){
            console.log('eat');
            }
        }
        function Y(){
            Fy.call(this)
        }
        // 把Fy原型赋给Y的原型
        // Y.prototype = Fy.prototype
    
        // Object.create创建一个对象,里面传一个对象
        Y.prototype = Object.create(Fy.prototype);
        // 更改Y原型的Y指向
        Y.prototype.constructor = Y
    
        var c = new Y();
        var d = new Y();
        c.color.push('5');
        console.log(d.color)
    
        
        // typeof 判断数据类型
        // instanceof 判断前者是否在后者的原型对象里
        console.log(c instanceof Y);
        console.log(c instanceof Fy);
    
        </script>
    </body>
    </html>
    

    相关文章

      网友评论

        本文标题:JS闭包-继承

        本文链接:https://www.haomeiwen.com/subject/qlzngqtx.html