js计算练习


<!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>Document</title>
</head>
<script>
    // function sum(...x) {
    //     var s = 0;
    //     for(var i = 0;i<x.length;i++){
    //         // s ++
    //         s += x[i];
    //     }
    //     var sum_fn = function (...y) {
    //         for(var i = 0;i<y.length;i++){
    //             //s++
    //             s +=y[i];
    //         }
    //         return sum_fn;
    //     }
    //     sum_fn.valueOf = function(){
    //         return s;
    //     }
    //     return sum_fn;
    // }

    function sum (...x) {
        var s = 0;
        for (var i = 0;i<x.length;i++){
            s+=x[i];
        }
        var sum_fn = function(...y) {
            for (var i = 0;i<y.length;i++){
                s +=y[i];
            }
            return sum_fn;
        }
        sum_fn.valueOf = function(){
            return s;
        }
        return sum_fn;
    }
    function sum (...x){
        var s = 0;
        const add = arr=>arr.forEach(a=>s+=a);
        add(x);
            var sum_fn = function(...y) {
                add(y);
                return sum_fn;
            }
        sum_fn.valueOf = function(){
            return s;
        } 
        return sum_fn;
    }
    console.log(sum(1)(2)(3)(4)(5).valueOf())
    console.log(sum(1,2,3,4)(5).valueOf())
    console.log(sum(1,2,3,4)(5).valueOf())
    console.log(sum(1,2,3)(4)(5).valueOf())
    console.log(sum(1,2)(3,4)(5).valueOf())
</script>
<body>
    
</body>
</html>
============

<!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>Document</title>
</head>
<body>
    <script>
// function add(...args){
//             var fn = args[0];
//             console.log(args)
//             var arr = fn();
//             var sum = 0;
//       if (typeof arr == "number"){
//                 sum = arr;
//             }
//             else {
//         sum = arr[0];
//                 for(var i = 0;i<arr.length - 1;i++){
//                // console.log(arr[i])
//                 sum += arr[i+1];
        
//             }
//       }
//             for(var i =1;i<args.length;i++){
//                // console.log(args[i])
//                 sum += args[i]
//             }
//             return function(){
//                 return sum
//             }
//         }

//          function subtract(...args){
//             var fn = args[0];
//             console.log(args)
//             var arr = fn(); //arr []
//             var sum ;
//             if (typeof arr == "number"){
//                 sum = arr;
//             }
            
//             else {
//         sum = arr[0];
//                 for(var i = 0;i<arr.length - 1;i++){
//                // console.log(arr[i])
//                 sum -= arr[i+1];
        
//             }
//       }
//             for(var i =1;i<args.length;i++){
//                // console.log(args[i])
//                 sum -= args[i]
//             }
//             return function(){
//                 return sum
//             }
//         }


//     function num(x){
//         var arr = [];
//         arr.push(x);
//         var num_fn = function(x){
//             if(!x) return arr;
//             else{
//                 arr.push(x);
//                 return num_fn;
//             }
//         }
//         return num_fn;
//     } 

//     console.log(add(add(num(3)(4)(5)),2,4)()) //6



    function mathss(args,q){
    var fn = args[0];
            console.log(args)
            var arr = fn();
            var sum = 0;
      if (typeof arr == "number"){
                sum = arr;
            }
            else {
        sum = arr[0];
                for(var i = 0;i<arr.length - 1;i++){
               // console.log(arr[i]) 
               q=1? sum += arr[i+1]:sum -= arr[i+1]
        
            }
      }
            for(var i =1;i<args.length;i++){
               // console.log(args[i])
                q=1?sum += args[i]:sum -= args[i]
            }
            return function(){
                return sum
            }
}


    function add(...args){
       return mathss(args,1)
    }
    
    function subtract(...args){
       return mathss(args,0) 
    }

     function num(x){
        var arr = [];
        arr.push(x);
        var num_fn = function(x){
            if(!x) return arr;
            else{
                arr.push(x);
                return num_fn;
            }
        }
        return num_fn;
    }

    console.log(add(add(num(3)(4)(5)),2,4)()) //6



   
    </script>
</body>
</html>
===============

<!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>Document</title>
</head>
<body>
    <script>
        function sum(...x){
            var s= 0;
            for(var i = 0;i<x.length;i++){
                s=x[i];
            }
            var sum_fn=function(...y){
                for(var i =0;i<y.length;i++){
                    s+=y[i];
                }
                return sum_fn
            }
            sum_fn.valueOf = function(){
                return s;
            }
            return sum_fn; 
        }

        function sum(...x){
            var s = 0;
            for(var i = 0;i<x.length;i++){
                s +=x[i]
            }
            var sum_fn = function(...y){
            
            }



        function num(x){
            return function(a){
                return function(b){
                    return function(c){

                    }
                }
            }
        }

        function nun(x){
            var arr = [];
            arr.push(x);
            var num_f=function(x){
                if(!x) return arr;
                else {
                    arr.push(x);
                    return num_f; 
                }
            }
            return num_f;
        }

        function num (x){
            var arr = [];
            arr.push(x);
            var num_fn = function(x){
                if(!x) return arr;
                else {
                    arr.push(x);
                    return num_fn;
                }
            }
            return num_fn;
        }

        function add(...args){
            var fn = args[0];
        }



        function add (...args ){
            var fn =args [0];
            var arr = fn();
            for(var i =0;i<arr.length;i++){
                console.log(arr[i])
            }
            for(var i =1;i<args.length;i++){
                console.log(args[i])
            }
            return function(){
                return
            }
        }
        function num(x){
            var arr = [];
            ar.push(x);
            var num_fn = function (x) { 
                if(!x) return arr ;
                eles {
                    arr.push(x);
                    return num_fn;
                }
            }
            return num_fn;
        }
        add(num(4)(6),2,4,6)



        function add(...args){ 
            var fn = args[0]; 
            var arr = fn();
            var arrr = fn();
            for(var i  = 0;i<arr.length;i++){

            }
            }
    </script>
</body>
</html>
=======

<!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>Document</title>
</head>
<body>
    <!-- 闭包 -->
    <!-- 函数作为返回值 -->
    <!-- 高阶函数除了可以接受函数作为参数外,还可以把函数作为返回值返回 -->
    <script>
        // function sum(arr){
        //     debugger;
        //     return arr.reduce(function(x,y) {
        //         return x+y
        //     })
        // }
        // console.log(sum([1,2,3,4,5]))

        // 但是,如果不需要立刻求和,而是在后面的代码中,根据需要在计算怎么办?
        // 可以不返回求和的结果,返回求和的函数
        function lazzy_sum(arr) {
            var sum = function(){
                return arr.reduce(functon(x,y){
                    return 
                })
            }
        }
    </script>
</body>
</html>
============

<!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>Document</title>
</head>
<body>
    <script>
        // var two = function(x){
        //     typeof x == 'function'?x(2) :2;
        // }
        // var one = function(x){
        //     typeof x == 'function'?x(1):1;
        // }
        // var three = function(x){
        //     typeof x == 'function'?x(3):3;
        // }
        var two = x=>typeof x =='function'?x(2):2; 
        var one = x=>typeof x =='function'?x(1):1;
        var tthreewo = x=>typeof x =='function'?x(3):3;
        var add = function(a){
            return function(b){
                return a + b;
            }
        }
       console.log( one(add(two())))
    </script>
</body>
</html>
==================

<!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>Document</title>
</head>
<body>
    <script>
        function checkName(){

        }
        function checkEmail(){

        }
        function checkPassword(){

        }
        //这种在用的时候需要提前声明
        var checkName = function(){
            //验证姓名
        }
        var checkEmail = function(){
            //验证邮箱密码
        }
        var checkPassword = function(){
            //验证密码
        }
        //对象有属性和方法,而如果我们要访问它的属性或者方法时,可以通过点语法向下遍历
        //查询得到。我们可以创见一个检测对象,然后把我们的方法放在里面
        var ChckObject = {
            checkName:function(){
                //验证密码
            },
            checkEmail:function(){
                //验证邮箱
            },
            checkPassword:function(){
                //验证密码
            }
        }
        //此时我们将所有的函数作为CheckObjectd对象的方法,这样我们就有一个对象,而我们想要
        //使用它很简单,比如检测姓名CheckObject.checkName(),只是我们原来使用的函数式前面
        //多了一个对象名称

        //既然我们可以通过.的语法来使用,是不是也可以通过.的语法创建呢?
        //是的前提是你要声明一个对象,然后给它添加方法,当然在js中函数也是对象
        var CheckObject = function(){

        }
        CheckObject.checkName=function(){
            //验证姓名
        }
        CheckObject.checkEmail=function(){
            //验证邮箱
        }
        CheckObject.checkPassword=function(){
            //验证密码
        }
        //使用和前面的方式是一样的,比如CheckObiect.checkName(),现在虽然能满足你的需求
        //别人想用你写的对象方法时就有一些麻烦了,因为这个对象不能复制一份,或者说这个对象
        //类再用new个关键字创新的对象时,新创建的对象是不能继承这个方法的

        //真假对象
        //如果你简单地复制一下,你可以将方法放在一个函数对象中。
        var CheckObject = function(){
            return {
                checkName:function(){
                    //验证姓名
                },
                checkEmail:{
                    //验证邮箱
                },
                checkPassword:{
                    //验证密码
                }
            }
        }

        var a = CheckObject();
        a.checkEmail();
        //虽然通过创建了新对象完成了我们的需求,但是他不是一个真正意义上类的创建方式,并且创建
        //的对象a和对象CheckObject没又任何关系(返回出来的对象本身就与Object对象无关)
        var ChckObject=function(){
            this.checkName=function(){
                //验证名字
            }
            this.checkEmail=function(){
                //验证邮箱
            }
            this.checkPassword=function(){
                //验证密码
            }
        }
        //像上面这样就可以用CheckObject类创建出来的对象了
        //我们把所有的方法放在函数内部了,通过this定义的,所以每一次通过new关键字创建
        //新对象的时候,新创建的对象都会对类的this上的属性进行复制。所以这些新创建的
        //对象都会有一套方法,然而有时候这么做消耗是很奢侈的,我们需要处理一下
        var CheckObject=function(){};
        CheckObject.prototype={
            checkName:function(){

            },
            checkEmail:function(){

            },
            checkPassword:function(){

            }
        }
        //但有一点要记住,这两种方式不能混淆着用,否则一旦混用,如果在后面为对象的原型对象
        //赋值新对象时,那么它将会覆盖掉之前对propotype对象赋值的方法。
        //使用这种方式定义的类
        var a = new CheckObject();
        a.checkName();
        a.checkEmail();
        a.checkPassword();
         //调用了3个方法,但是你对对象a书写了三遍。这是可以避免的。那就要在你生命的每一个方法
         //末尾处将当前对象返回,在JavaScript中this指向就是当前对象,所以你可以将它返回。例如
         //我们开始写的第一个对象还记得吗
         var CheckObject = {
             checkName:function(){
                 //验证名字
                 return this;
             },
             checkEmail:function(){
                 //验证邮箱
                 return this
             },
            checkPassword:function(){
                //验证密码
                return this
            }
         }
         //此时使用他就可以这样
         CheckObject.checkName().checkEmail().checkPassword();
         //当然同样的让是还可以放到类的原型当中
         var CheckObject = function(){}
         CheckObject.prototype={
             checkName:function(){
                 //验证姓名
                 return this;
             },
             checkEmail:function(){
                 //验证邮箱
                 return this;
             },
             checkPassword:function(){
                 return this;
             }
         }
         //但使用时候也要先创建一下
         var a = new CheckObject();
         a.checkName().checkEmail().checkPassword();
         //如果你想给每一个函数都添加一个检测有限狗的方就可以这样做
         Function.prototype.checkEmail = function(){
             //验证邮箱
         }
         //这样在使用这个方法就方便多了啦,如果你喜欢函数形式
         var f= function(){

         }
         f.checkEmail();
         //如果你习惯类的形式
         var f = new Function();
         f.checkEmail();
         //但是这么做事不允许的,因为污染了原生对象Function,所以别人创建的函数也会被你
         //创建的函数所污染,造成不必要的开销,但是你可以抽象出来一个统一添加方法的功能
         Function.prototype.addMethod = function(name,fn){
             this[name] = fn;
         }
         //这样如果你想添加邮箱验证和姓名验证方法你可以这样做
         var methods= function(){}
         //或者
         var methods = new Function();
         methods.addMethod('checkName',function(){
             //验证姓名
         });
         methods.addMethod('checkName',function(){
             //验证邮箱
         });
         methods.checkEmail();
         methods.checkName();

         //可以链式添加嘛
         Function.prototype.addMethod = function(name,fn){
             this[name]=fn;
             return this;
         }

         //如果你在想添加方法就可以这样了
         var methods = function(){};
         methods.addMethod('checkName',function(){
             //验证姓名
         }).addMethod('checkEmail',function(){
             //验证邮箱
         })
         //既然添加方法的时候可以将this返回现实,那么添加的每个方法将this返回
         var methods = function(){};
         methods.addMethod('checkName',function(){
             //验证姓名
             return this;
         }).addMethod('checkEmail',function(){
             //验证邮箱
             return this;
         })
         methods.checkName().checkEmail()

         //可是在你测试的时候,你用的是函数式调用方式?对于习惯于类式调用方式的同学来说
         //他们可以这样简单的改一下
         Function.prototype.addMethod = function(name,fn){
             this.prototype[name] = fn;
             return this;
         }
         //此时我们还按照上一种方式添加方法
         var Methods = function(){}
         Methods.addMethod('checkName',function(){
             //验证姓名
         }).addMethod('checkEmail',function(){
             //验证邮箱
         })
         var m = new Methods();
         m.checkEmail()


         //2.2包装明星-封装
         //2.21创建一个类
         //在js中创建一个类很容易,首先声明一个函数保存在一个变量里。按编程习惯将这个代表
         //类的变量名首字母大写。然后在这个函数(类)的内部通过对this(函数内部自带的一个变量,
         //用于指向当前这这个对象)变量添加属性或者方法来实现对类添加属性或者方法 例如:
         var Book = function(id,bookname,price){
             this.id = id;
             this.bookname = bookname;
             this.price = price;
         }
         //"也可以通过在类圆形(类也是一个对象,所以也有原型prototype)上添加属性和方法有两种
         //方式,一种是一一为原型对象属性赋值,另一种是将一个对象赋值给类的原型对象,但这
         //两种不用混用,例如。"
         Book.prototype.display = function(){
             //展示这本书
         };
         //或者
         Book.prototype = {
             display : function(){}
         }
         //这样我们将所需的方法和属性都封装在我们抽象的Book类里面了,当使用功能方法时,我们
         //不能直接使用这个Book类,需要用new关键字来实例化(创建)新的对象。使用实例化的属性
         //或者方法时,可以通过点语法访问,例如
         var book = new Book(10,'设计模式',50);
         console.log(book.bookname)//设计模式

         //私有属性和私有方法,特权方法,对象共有属性和对象共有方法,构造器
         var Book = function(id,name,price){
             //私有属性 
             var num = 1;
             //私有方法
             function checkId(){

             }; 
             //特权方法
             this.getName = function(){}
             this.getPrice = function(){}
             this.setName = function(){}
             this.setPrice = function(){}
             //对象公有属性
             this.copy = function(){}
             //构造器
             this.setName(name);
             this.setPrice(price);
         }

         //类静态公共有属性(对象不能访问)
         Book.isChinese = true;
         //类静态公有方法(对象不能访问)
         Book.resetTime = function(){
             console.log('new Tiem')
         };
         Book.prototype = {
             //公有属性
             isJSBook:false,
             //公有方法
             display:function(){}
         }
         //通过new关键字创建的对象实质是对新对象this的不断赋值,并将prototype指向类的prototype所指向的对象,而类的构造函数外面通过
         //点语法定义的属性方法是不会添加到新创建的对象上去的。因此要想在新创建的对象中使用inChinese就得通过Book类使用而不能通过this,
         //如Book.inChinese,而类的原型prototype上定义的属性在新对象里就可以直接使用,这是因为新对象的prototype和类似的prototype指向
         //的是同一个对象
         var b = new Book(11,'JavaScript',50); 
         console.log(b.num)                     //undefined
         console.log(b.isJSBook)                //false
         console.log(b.id)                      //11
         console.log(b.inChinese)               //undefined
         //类的私有属性num以及静态共有属性inChinese在新创建的b对象里是访问不到的。而类的共有属性isJSBook在b对象中却可以通过点语法访问到
         //但是类的静态公有属性inChinese可以通过类的自身访问
         console.log(Book.inChinese); //true
         Book.resetTime(); //new Tiem
         
         //我们经常将类的静态变量通过闭包来实现
         var Book = (function(){
             //静态私有变量
             var bookNum = 0;
             //静态私有方法
             function checkBook (name){

             }
             return function(newId,newNmae,newPrice) {
                 //私有变量
                 var name,price;
                 //私有方法
                 function checkId(id){}
                 //特权方法
                 this.getName = function(){};
                 this.getPrice = function(){};
                 this.setName = function(){};
                 this.setPrice = function(){};
                 //公有属性
                 this.id = newId;
                 //公有方法
                 this.copy = function(){};
                 bookNum++
                 if(bookNum > 100)
                    throw new Error('大萨达')
                //构造器
                this.setName(name);
                this.setPrice(price);
             }
         })()
         Book.prototype = {
             //静态公有属性
             isJSBook:false,
             //静态公有方法
             display:function(){}
         }
         
         //闭包是有权访问另外一个函数作用域中变量的函数,即在一个函数内部创建另外一个函数。我们将这个闭包作为创建对象的构造函数,这样
         //它既是闭包又是实例对象的函数,即可访问到类函数作用域中的变量,如bookNum这个变量,此时这个变量叫静态私有变量,并且checkBook()
         //可称为静态私有方法。当然闭包内部也有其自身的私有变量以及私有方法如pricce,checkID()。但是,在闭包外部添加言行属性和方法看上去
         //像是脱离了闭包这个类,所以有时候在闭包内部实现一个完整的类然后将其返回,看下面的例子
         //利用闭包实现
         var Book = (function(){
             //静态私有变量
             var bookNum = 0;
             //静态私有方法
             function checkBook(name){

             }
             //创建类
             function book(newId,newName,newPrice){
                 //私有变量
                 var name,price;
                 //私有方法
                 function checkID(id){}
                 //特权方法
                 this.getName = function(){};
                 this.getPrice = function(){};
                 this.setName = function(){};
                 this.setPrice = function(){};
                 //公有属性
                 this.id = newId;
                 //公有方法
                 this.copy = function(){}
                 bookNum++
                 if(bookNum>100)
                    throw new Error('我们啦啦啦啦啦');
                //构造器
                this.setName(name);
                this.setPrice(price);
             }
             //构造原型
             _book.prototype = {
                 //静态公有属性
                 isJSBook:false,
                 //静态公有方法
                 display:function(){}
             }; 
             //返回类
             return _book;
         })();

         //一般对初学者来说,在创建对象上由于不适应这种写法,所以经常容易忘记使用new而犯错误,如果犯错误有人实时监测就解决了
         //所以找一位检查长,比如JavaScript在创建对象时有一种安全模式就完全可以解决你们这类问题
         //图书类
         var Book = function(title,time,type){
            this.title = title;
            this.time = time;
            this.type = type;
         }
         //实例化一本书
         var book = Book('JavaScript','2014','js');
         console.log(book);//undefined
         console.log(window.title);//Javescript
         console.log(window.time);//2014
         consoe.log(window.type);//js
         //怎么样发现问题了吗,
         //明明创建了一个Book对象,并添加了title、time、type3个属性,怎么会添加到window上面去了,而且book这个变量还是Undefined。
         //因为没有new是实例化对象,可是为什么会出现这个结果呢
         //首先你要明白一点,new关键字的作用可以看做是对当前你对象this不停地赋值,然而例子中没有用new,所以就会直接直接执行这个函数,
         //而这个函数在全局作用域中执行了,所以在全局作用域中this指向的当前对象自然就是群居变量,再这个页面中全局变量就是window了,
         //所以添加的属性自然就会被添加到window上面了,而我们这个book变量最终的作用是要得到Book变量的执行结果了,所以就是undefind
         //(未定义) 该如何避免呢
         //去找位检查长 使用安全模式
         //图书安全类
         var Book = function(title,time,type) {
             //判断执行过程中this是否是当前这个对象(如果是说明是用new创建的)
             if(this instanceof Book) {
                 this.title = title;
                 this.time = time;
                 this.type = type;
                 //否则重新创建这个对象
             }else {
                 return new Book(title,time,type);
             }
         }
         var book = Book('JavaScript','2014','js');
         //测试
         console.log(book); //Book
         console.log(book.title);//JavaScript
         console.log(book.time);//2014
         console.log(book.type);//js
         console.log(window.title);//undefined
         console.log(window.time);//undefined
         console.log(window.type);//undefined

         //继承
         //子类的运行对象-类式继承
         //声明父类
         function SuperClass(){
             this.SuperClass = true
         }
         //为父类添加共有方法
         SuperClass.prototype.getSuperValue = function(){
             return this.superValue
         }
         //声明子类
         function SubClass(){
             this.subValue = false;
         }
         //继承父类
         SubClass.prototype = new SuperClass();
         //为子类添加共有方法
         SubClass.prototype.getSubValue = function(){
             return this.subValue
         }
         //继承混简单就是声明2个类而已,不过类式继承需要将一个诶的实例赋值给第二个类的原型
         //类的原型对象的作用就是为类的原型添加共有方法,但类不能直接访问这些属性和方法,
         //必须通过原型propototype来访问。而我们实例化一个父类的时候,新创建的对象复制了父类
         //的构造函数内的属性与方法并且将原型_proto_指向了腹肌的原型对象,这样就拥有了父。类的原型对象
         //上的属性与方法,并且这个新创建的对象可直接访问到父类原型对象上的属性与方法。如果我们将这个新创建的
         //对象赋值给字类的原型,那么子类的原型就可以访问到父类的原型属性和方法
         //补充一点,上面说的新创建的对象不仅仅可以访问父类原型上的属性和方法,同样也可访问从父类构造函数中复制的属性和方法
         //你将这个对象赋值给子类对像的原型,那么这个子类的原型同样可以访问父类原型上的属性和方法与从父类构造函数中复制的
         //属性和方法。这正是类式继承的原理
         //使用子类
         var instance = new SubClass();
         console.log(instance.getSuperValue());//true
         console.log(instance.getSubValue());//false
         //另外还可以通过instanceof来检测某个对像是否是某个类的实例,或者说某个对像是否继承了某个类。这样就可以判断对像之间的
         //继承关系了 instanceof是通过判断对像的prototypr链来确定这个对象是否是某个类的实例,而不关心对象与类的自身结构
         //测试代码
         console.log(instance instanceof SuperClass)
         console.log(instance instanceof SubClass)
         console.log(SubClass instanceof SuperClass)
         //我们说subClass继承superClass,可是为什么SubClass instanceof SuperClass得到的结果是false呢?
         //前面说了,instanceof是判断前面的兑现是否是后面类(对象)的实例,它并不表示两者的继承,这一点不要弄混了,其次
         //我们看看前面的代码,你看我们在实现subClass继承SuperClass时是通过将superClass的实例赋值给subClass的原型prototype,
         //所以说SubClass.prototype继承了superClass
         console.log(SubClass.prototype instanceof SuperClass);//true
         //这种类式继承还有2个缺点其一,由于子类通过其原型prototype对父类实例化,继承了父类。随意说父类中的共有属性要是引用类型,
         //就会在子类中被所有实例公用,因此一个子类的实例更改子类原型从父类构造函数中继承来的共有属性就会直接影响到其他子类,
         //比如你看下面的代码
         function SuperClass () {
             this.books = ['JavaScript','html','css'];
         }
         function SubClass () {}
         SubClass.prototype = new SuperClass();
         var instance1 = new SubClass();
         var instance2 = new SubClass();
         console.log(instance2.books);//["JavaScript","html","css"]
         instance1.books.push('设计模式');
         console.log(instance2.books);//["JavaScript","html","css","设计模式"]
         //“instance1的一个无意的修改就会无情地伤害了instance2的book属性,这在编程中很容易埋藏陷阱。其2二,由于子类实现的继承是靠其
         //原型prototype对父类的实例化实现的,因此在创建父类的时候,是无法向父类传递参数的,因而在实例化父类的实例化实现的,因此在
         //创建父类的时候,是无法向父类传递参数的,因而在实例化父类的时候也无法对父类构造函数内的属性进行初始化”
         //那我们该如何解决呢
         //构造函数继承
         //声明父类
         function SuperClass (id) {
             //引用类型共有属性
             this.books = ['JavaScript','html','css'];
             //值类型共有属性
             this.id = id;
         }
         //父类声明原型方法
         SuperClass.prototype.showBook = function(){
             console.log(this.books);
         }
         //声明子类
         function SubClass(id){
             //继承父类
             SuperClass.call(this,id);
         }
         //创建第一个子类实例
         var instance2 = new SubClass(10);
         //创建第二个子类的实例
         var instance2 = new SubClass(11);
         insyance1.books.push("aaa");
         console.log(instance1.books);//["JavaScript","html","css","aaa"];
         console.log(instance1.id);   //10
         console.log(instance2.books);//["JavaScript","html","css"]
         console.log(instance2.id);  //11
         instance1.books();          //TypeError2
         //注意这里,SuperClass.call(this,id);这条语句手机构造函数式继承的精华,由于call这个方法可以更改函数的作用环境,因此
         //在子类中,对superClass调用这个方法就是将子类中的变量在父类中执行一遍,由于父类中是 给this绑定属性的,因此子类自然也就
         //继承了父类的共有属性。由于这种类型的继承没有涉及原型prototype,所以父类的原型方法自然不会被子类继承,而如果想要被子类
         //继承就必须要放在构造函数中,这样创建出来的每个实例都会单独拥有一份而不能公用,这样就违背了代码复用的原则。为了综合这
         //两种模式的有点,后来又了组合继承
         //组合继承
         //组合继承是不是说将这两种继承模式综合到一起呀?那么它又是如何做到的你?
         //我们先总结一下之前两种模式的特点,类式继承是通过子类的原型prototype对父类实例化来实现的,构造函数式继承是通过在子类的构造函数
         //作用环境中执行一次父类的构造函数来实现的,所以只要在继承中同时做到这两点即可,
         //组合继承
         //声明父类
         function SuperClass (name) {
             //值类型共有属性
             this.books = ["html","css","JavaScript"];
         }
         //父类原型共有方法
         SuperClass.prototype.getName = function(){
             console.log(this.name);
         };
         //声明子类
         function SubClass(name,time){
             //构造函数式继承父类name属性
             SuperClass.call.call(this,name);
             //子类中新增共有属性
             this.time = time;
         }
         //类式继承 子类原型继承父类
         SubClass.prototype = new SuperClass();
         //子类原型方法
         SubClass.prototypr.getTime = function(){
             console.log(this.time);
         }
         //在子类构造函数中执行父类构造函数,在子类的原型上实例化父类就是组合模式,在这样就融合了类式继承和构造函数继承的有点,
         //并且过滤掉其缺点,测试看看
         var instance1 = new SubClass("js book",2014);
         instance1.books.push("设计模式");
         console.log(instance1.books);//["html","css","JavaScript","设计模式"]
         instancal.getName();//js book
         instance1.getTime();//2014

         var instance2 = new SubClass("css book",2013);
         console.log(instance2.books);//["html","css","JavaScript"]
         instance2.getName();         //css book
         instance2.getTime();         //2013
         //子类的实例中更改父类继承下来的引用类型属性如books,根本不会影响到其他实例,并且子类实例比例化过程中又能将参数传递到父类的
         //构造函数中,如name。这种模式真的很强大,所以这应该是继承中最完美的版本吧
         //还不是,因为我们在使用构造函数。因此父类构造函数调用了两遍,所以这还不是最完美的方式。
         //原型式继承
         //2006年道格拉斯.克罗克福德发表一篇《JavaScript 中原型式继承》的文章,他的观点是,借助原型prototype可以根据已有的
         //对象创建一个新的对象,同时不必创建新的自定义对象类型。大师的话理解起来可能很困难,不过我们还是现看一下他实现的代码吧
         //原型是继承
         function inheritObject(o){
             //声明一个过渡函数对象
             function F(){}ttyyyyyyyyy
         }
    </script>
</body>
</html>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章