美文网首页
js_函数循环及原型(二)

js_函数循环及原型(二)

作者: mao77_ | 来源:发表于2019-02-08 20:14 被阅读0次

    js_(二)

    1. for循环的一些细节

        var i = 1;
        var sum = 0;
        while(i <= 100){
            sum += i;
            i++;
        }
        console.log(sum);
    

    2. 函数的认识

    函数是是具有特定功能的代码

    • 避免代码重复
    • 方便管理和维护,便于复用
    • 有利于程序维护和开发效率。

    2.1 - 使用函数的步骤

    • 先声明函数(定义函数)
    • 调用函数
    • 形参在函数内部就当作一个普通的变量来使用。

    2.2 - 输出范围内的所有的整数的和。

        function add(from, to) {
            var sum = 0;
            for(var i=from; i<=to; i++){
                sum += i;
            }
            console.log(sum);
        }
        add(10, 100);
    

    2.3 - 一个数,计算是否为质数

        function number(num) {
            var flag = true;
            for(var j=2, v=Math.sqrt(num); j<=v; j++){
                if(num % j == 0){
                    flag = false;
                    break;
                }
            }
            if(flag){
                console.log(num + "是质数");
            }else {
                console.log(num + "是合数");
            }
        }
        var num = prompt("shuru");
        number(num);
    

    3. 函数的返回值

    • 函数三要素
      1. 函数名
        • 动词多一些
        • 驼峰命名,不能数字开头
        • 见名知意(做不到就加注释)
      2. 形参
        • 形参如何定义
        • 需要与否,需要多少。
      3. 返回值
        • 函数返回给调用者的函数计算出来的结果。
    • 在函数内部使用return来把数据返回给函数的调用者
    • 两个作用:
      1. 给调用者返回值;
      2. 只要在函数内部碰到return,则立即把返回值给调用者,同时会立即结束函数的执行。

    3.1 - 一个数,计算是否为质数

        /**
         * 判断一个指定的数是否为质数
         * @param num 就是指定的要判断的那个整数
         * @return 如果传入的数是质数,则返回true,否则返回false
         */
        function isPrime(num){
            for(var i=2; i<num; i++){
                if(num % i == 0){
                    return false;
                }
            }
            return true;
        }
        var n = 6;
        if(isPrime(n)){
            console.log(n + "是质数");
        }else {
            console.log(n + "是合数");
        }
    

    3.2 - 求质数和

        function isPrime(num){
            for(var i=2; i<num; i++){
                if(num % i == 0){
                    return false;
                }
            }
            return true;
        }
        function sumPrimes(from, to) {
            var sum = 0;
            for(var i=from; i<=to; i++){
                if(isPrime(i)){
                    sum += i;
                }
            }
            return sum;
        }
        function sumHeshu(from, to) {
            var sum = 0;
            for(var i=from; i<=to; i++){
                if(!isPrime(i)){
                    sum += i;
                }
            }
            return sum;
        }
        console.log(sumPrimes(1, 100));
        console.log(sumHeshu(1, 100));
        
        //---------------------------------
        
        // function sumPrimes(from, to) {
        //     var sum = 0;
        //     for(var i=from; i<=to; i++){
        //         var flag = true;
        //         for(var j=2; j<i; j++){
        //             if(i % j == 0){
        //                 flag = false;
        //                 break;
        //             }
        //         }
        //         if(flag){
        //             sum += i;
        //         }
        //     }
        //     return sum;
        // }
    

    3.3 - 阶乘和

        function Jc(num){
            var plus = 1;
            for(var i=num; i>0; i--){
                plus *= i;
            }
            return plus;
        }
        function JcAdd(from, to){
            var sum = 0;
            for(var i=from; i<=to; i++){
                sum += Jc(i);
            }
            return sum;
        }
    
        console.log(JcAdd(1, 10));
        
        //--------------------------------
        
        function jcAdd(from, to){
            var sum =0;
            var plus = 1;
            for(var i=from; i<=to; i++){
                plus *= i;
                sum += plus;
            }
            return sum;
        }
    
        console.log(jcAdd(1, 10));
    

    4. 关于函数的返回值数方面的一些细节

    • 函数没有return,一直运行到函数的最后一行代码。
      • 默认返回值是undefined.
    • return后面可以不跟任何数据。这个时候返回值也为undefined。
      • 这个时候其实是为了让函数立即结束

    5. 匿名函数

    • 如果一个变量,给它赋一个函数,它就叫做函数表达式。
        var foo = function () {
            console.log(a);
        };
        console.log(foo);
        foo();
    
    • 匿名函数的作用
    1. 给变量赋值,成为函数表达式,那么这个变量就当作一个正常的函数来使用。
    2. 封装私有数据
      • 配合函数的自调用/自执行
    3. 作为参数传递,和作为返回值返回。(高阶函数)
        (function () {
            console.log("a");
        }) ();
        
        //----------------写法意义是相通的。
        
        (function () {
            console.log("a");
        }());
    

    6. 函数的递归调用

    函数自己调用自己

    • 一定要有两个条件:
      1. 一定要有递归结束的条件
      2. 随着递归的深入,一定要能达到这个结束的条件
        function jiecheng(n) {
            if(n == 1) return 1;
            return n * jiecheng(n - 1);
        }
    
        console.log(jiecheng(5));
    

    7. 原型

    1. JS中一切皆对象
    2. 只要是对象,都可以有自己的属性
    3. 作为一个函数对象,也会有自己的属性
    4. 当完成一个函数声明之后,JS引擎会自动的创建一个对象,这个对象表示函数对象
    5. 函数对象会有一个属性prototype,他指向一个对象,这个对象也是自动创建出来的。这个对象就是函数的原型对象。
    6. 原型对象也有一个属性constructor,表示构造器,他会指向函数对象
    7. 任何的函数都会有原型对象,只是我们只关注和研究构造函数的原型对象,普通函数的原型对象我们不关注
        function Person(){
    
        }
    
        console.log(Person.prototype);
        console.log(Person.prototype.constructor === Person);
    
      function Father() {
        this.name = 'eloise'
      }
    
      Father.prototype.giveMoney = function () {
        console.log('im eloise, hello');
      }
    
      function Son() {
        this.age = '2222'
      }
    
      Son.prototype = new Father();
      var s = new Son();
      console.log(s.age);
      console.log(s.name);
      s.giveMoney()
    

    8. 动态原型

        function Person(name, age){
            this.name = name;
            this.age = age;
            // if(Person.prototype.speak != "function"){
            if(!Person.prototype.speak){
                Person.prototype.speak = function(){
                    return this.name + "say:hi";
                };
                Person.prototype.smile = function(){
                    return this.age + "smile";
                };
                Person.prototype.kneel = function(){
                    return this.name + this.age + "lalala";
                }
            }
        }
    
    1. 初次运行的时候,Person.prototype.speak为false,取反为true,进入循环。
    2. 第二次运行的时候,Person.prototype.speak已有方法,可以通过内容访问到,因此不会进入到if方法中,避免原型方法的重复定义
    3. 如果去掉if的话,你每new一次(即每当一个实例对象生产时),都会重新定义一个新的函数,然后挂到Person.prototype.speak属性上。而实际上,你只需要定义一次就够了,因为所有实例都会共享此属性的。所以如果去掉if的话,会造成没必要的时间和空间浪费;而加上if后,只在new第一个实例时才会定义speak方法,之后就不会了。

    9. 原型替换法

    9.1 - 方法一

        function Person(name){
            this.name = name;
        }
        Person.prototype = {
            constructor : Person,
            speak: function(){
                console.log(this.name + "say:hi·");
            },
        };
        var p1 = new Person("李四");
        p1.speak();
    

    9.2 - 方法二

        function Person(name, age){
            this._init(name, age);
        }
        Person.prototype = {
            _init : function(name, age){
                this.name = name;
                this.age = age;
            }
            constructor : Person,
            speak: function(){
                console.log(this.name + "say:hi·");
            },
            say: function(){
    
            },
        };
        var p1 = new Person("李四");
        p1.speak();
    

    9.3 - 方法三(无敌)

        function Person(opt){
            this._init(opt);
        }
        Person.prototype = {
            _init : function(opt){
                // this.name = opt.name;
                // this.age = opt.age;
                Object.assign(this, opt);
            }
            constructor : Person,
            speak: function(){
                console.log(this.name + "say:hi·");
            },
            say: function(){
    
            },
        };
        var p1 = new Person({name:"lisi", age:22});
        p1.speak();
    

    10. 与原型相关的几个属性和方法

    1. 构造函数有一个属性prototype,指向原型对象
    2. new出来的对象会有一个不可见的属性[[proto]],指向函数的原型对象
    3. 游览器私自实现了一种方式去访问这个不可见的属性属性名.__proto__
        function Person(){
    
        }
        var p1 = new Person();
        console.log(p1.__proto__);
        console.log(Person.prototype === p1.__proto__);
    
    1. in 操作符
      • 用来查找属性是否在这个对象上存在,
      • 先在当前对象找,找不到就去原型上去找
      function Person(){
          this.name = "eloise";
      }
      Person.prototype.age = 10;
      var p1 = new Person();
      console.log("name" in p1);   //true
      console.log("age" in p1);    //true
      console.log("sex" in p1);   //false
      
    2. hasOwnProperty
      • 只在自己身上找,不在原型上找。
      function Person(){
          this.name = "eloise";
      }
      Person.prototype.age = 10;
      var p1 = new Person();
      console.log(p1.hasOwnProperty("name"));   //true
      console.log(p1.hasOwnProperty("age"));    //false
      console.log(p1.hasOwnProperty("sex"));    //false
      

    11. 对象的判断

    • 如果两个对象比较相等。= = =/= =,都是比较内存地址
    • 如果一端是基本类型,一端是对象
      • === 肯定是false
      • == 会先变成基本类型,然后再用基本类型的规则进行比较
        • 先调用这个对象的valueof方法,如果返回的是基本类型数据,则用这个基本类型的数据进行比较,默认valueof返回的是对象自己。
        • 如果返回的是对象,然后使用toString()方法,默认返回的是这样的一个字符串"[object Object]"
        var a = {
            age : 10,
            valueOf : function(){
                return 0;
            }
            // toString : function(){
            //     return 1;
            // }
        };
        var b = {};
        console.log(a == "");    //true
        console.log(a == "[object Object]");    //true
        console.log(b == "[object Object]");    //true
        

    相关文章

      网友评论

          本文标题:js_函数循环及原型(二)

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