美文网首页
js_继承及原型链等(四)

js_继承及原型链等(四)

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

    js_继承及原型链等(三)

    1. 继承

    • 依赖于原型链来完成的继承
    • 发生在对象与对象之间
    • 原型链如下
    
      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()
      
      console.log(Father.prototype.__proto__); //Object[[proto]]
      console.log(Object.prototype.__proto__);   //null
    
    • ==原型链是查找属性和方法的路径==
    • 原型链的顶端,一般认为就是Object的原型对象(或者是Null)
    • Object的proto指向null(原型链最顶端?/)

    2. 继承中属性的共享问题

    • 函数中的this到底是谁,和这个函数声明在什么地方没有关系,只和调用方式有关系
    1. 对象.方法()
    2. new构造函数()
    3. 函数()
      • 直接调用函数,函数中的this是window

    2.1 - 函数的借调

    call

    • ==函数.call()==
    • 每个函数对象a的都有一个方法call,使用这个方法也可以调用函数a。
    • 它可以指定a中的this是一个指定的对象。
          function Father(name, say){
              this.name = name;
              this.say = say;
          }
          Father.prototype.speak = function(){
              console.log("我是父类型的方法。speak");
          }
          function Son(age, name, say){
              // this.name = name;
              // Father(name);   this.name = window.name
              Father.call(this, name, say);    //静态方法
              //参数一: 重新指定Father中的this指向的是谁
              this.age = age;
          }
          Son.prototype = new Father("eloise");
          var s1 = new Son(10, "eloise2222", "helloWorld");
          var s2 = new Son(20, "eloise33333");
          // s1.__proto__.name = "eloise2222"; //又造成共享
          console.log(s1.name);
          console.log(s1.say);
          console.log(s2.name);
      
          // console.log(window.name);
      

    apply

    • ==函数.apply()==
    • 和call()的区别
      • 函数的实参的传递方式不同,call是一个一个的传递的
      • apply是传递一个数组,js引擎会自动的拆封
            function foo(a, b){
                console.log(this, a, b);
            }
            foo(10, 20);
            // foo.call({}, 20, 30);
            var arr = [20, 30];
            // foo.call({}, arr[0], arr[1]);
            foo.apply({}, arr);    //{}, 20, 30
        
        // var m = Math.max(10, 20, 40, 3, 5, 90);
        // console.log(m);
        
        var arr = [10, 20, 40, 3, 5, 90];
        // var m = Math.max.apply(Math, arr);  //this会出问题。
        var m = Math.max(...arr);   //展开运算符
        console.log(m);
        

    3. 函数借调的深入理解

        function foo(){
            console.log(this);
            console.log(this.age);
        }
        foo();   //undefined
        foo.call({age:20});    //20
        foo();   //undefined
    
        function foo(){
            console.log(this[0]);
        }
        foo();   //undefined
        foo.call([10, 20]);  //10
    
        window.age = 100;
        var obj1 = {
            age : 10,
            speak : function(){
                console.log(this.age);
            }
        }
        obj1.speak();   //10
        var f1 = obj1.speak;
        f1();   //100
    
        window.age = 10;
        function speak(){
            console.log(this.age);
        }
        var obj1 = {
            age: 20,
            speak : speak
        }
        var obj2 = {
            age : 30,
            speak:obj1.speak
        }
    
        speak();   //10
        obj1.speak();    //20
        obj2.speak();   //30
    

    3. 借调的应用

    1. typeof
    2. instanceof
    3. Array.isArray
    4. 测试内置类型
      • 借调Object.prototype上的toString
      • 对自定义类型,结果永远是[object Object]
          function foo(){
          }
          var arr = [];
          // console.log(foo.toString());
          console.log(Object.prototype.toString.call(foo));   //[object Function]
          console.log(Object.prototype.toString.call(arr));   //[object Array]
          console.log(Object.prototype.toString.call(3));   //[object Number]
          console.log(Object.prototype.toString.call(null));   //[object Null]
      

    4. 作用域链

    是变量或函数的查找路径

    5. 闭包

    理论基础就是作用域链

    • 认为闭包就是一个内部的函数
        function foo(){
            var a = 1;
            function f1(){   //闭包/但是不是很准确
                a++;
            }
            f1();
        }
        foo();
    
    • 闭包是内部函数和它访问的外部的局部变量的组合
    • 内部和它环境的组合
    • 形成闭包的冲要条件
      1. 一个内部函数(声明在函数内部的函数),如果访问了外部函数的局部变量,就一定会有闭包的产生
    • 特点
      • 会持有外部函数的局部变量,而且访问局部变量的时候,访问的到的一定是那个局部变量的最新的值
    • 当把闭包作为一个函数的返回值的时候,才会真正的有意义
        function foo(){
            var a = 10, b=20;
            function f1(){
                a++;
                b++;
                console.log(a, b);
            }
            return f1;
        }
    
        // var f = foo();    //在外部拿到了一个闭包
        // f();
        // f();
        var f1 = foo();   //返回一个闭包
        var f2 = foo();     //返回一个新的闭包
        f1();
        f2();
    

    5.1 - 闭包的应用

        //柯里化
        function addFun(m){
            return function f(n){
                return m + n;
            }
            return f;
        }
        var sum = addFun(5);
        console.log(sum(6));   //11
        console.log(sum(7));   //12
    

    6. 三个常用的高阶函数

    • 都是数组的方法;

    map //映射

    • 内部有内循环,可以对每一个元素做一个映射,然后映射出来的值会组成一个新的数组
        var arr = [10, 20, 30, 40];
        /*
        内部有内循环,可以对每一个元素做一个映射,然后映射出来的值会组成一个新的数组
         */
        // var mapArr = arr.map(function(e, index, self){
        //     return e * e * e;
        // });
        var mapArr = arr.map(e => e * e);   //拉姆达表达式  Lambda
        console.log(mapArr);    //[1000, 8000, 27000, 64000]
        console.log(arr);    //[10, 20, 30, 40]
    

    filter //过滤

    • 过滤函数,会把回调函数的返回值是true的那些元素给过滤出来,组成一个新的数组
        var arr = [10, 11, 20,33, 30, 40];
        var filterArr = arr.filter(function(e, index, self){
            return !(e % 2);
            // return index % 2;
        })
        /*
        过滤函数,会把回调函数的返回值是true的那些元素给过滤出来,组成一个新的数组
         */
        // var filterArr = arr.filter(e => e % 2);
        console.log(filterArr);
    
        //数组中的质数,平方之后的到新数组
        var arr = [10, 20, 30, 5, 9, 3, 17, 19];
        var filterArr = arr.filter(function(ele){
            for(var i=2; i<=ele/2; i++){
                return ele % i;
            }
        }).map(e => e * e).sort(function(a,b){
            return b-a;
        });
        console.log(filterArr);   //[361, 289, 81, 25]
    

    reduce //减少, 归纳

        var arr = [10, 20, 30, 5, 9, 3, 17, 19];
        var a = arr.reduce(function(pre, e, index, self){
            console.log(e, index, self);
            return pre * e;
        }, 1);   //初始值
        // var a = arr.reduce((pre, e) => pre * e, 1);
        console.log(a);   //113
    

    7. 回调函数的this丢失问题

        function foo(f){
            f();
        }
        var obj = {
            age : 20,
            f : function(){
                console.log(this.age);
            }
        }
        foo(obj.f);     //undefined
    
        var age = 30;
        function foo(f){
            f();
        }
        var obj = {
            age : 20,
            f : function(){
                console.log(this.age);
                foo(function(){
                    console.log(this.age);
                })
            }
        }
        obj.f();     //20    30;
    
    - 解决:
    ```
        var age = 30;
        function foo(f){
            f();
        }
        var obj = {
            age : 20,
            f : function(){
                var that = this;  //将动态的this变成变量that/self...
                //闭包的运用
                foo(function(){
                    console.log(that.age);
                })
            }
        }
        obj.f();      //20
    ```
    

    8. 字符串中一些常用的方法和属性

    • ==在JS中,字符串永远是不可变的==
      • 字符串的不可变性。(为了节省内存)
      • 很多方法,会有更改字符串的操作,都是重新创建了新的字符串而已
          var s1 = "abc你好";
          // console.log(s1.length);  //5
          console.log(s1.charAt(0));  //a
          console.log(s1[0]);
      
    • length: 返回字符串中字符的个数
    • charAt(index): 返回指定索引位置的字符,由于JS中没有字符类型,所以返回的是字符串类型的数据
    • s1[0]: 也可以使用方括号语法来访问字符串中的字符。
    • charCodeAt(index): 返回字符的Unicode码
        //生成随机的一个长度为4的字符串可以是数字可以是字母(大小写)
        //验证码
        // var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "A", "B"];
        var arr = [];
        for(var i=0; i<10; i++){
            arr.push(i + "")
        }
        for(var j=97, z="z".charCodeAt(0); j<=z; j++){
            arr.push(String.fromCharCode(j));
            arr.push(String.fromCharCode(j-32));
        }
        var s = "";
        for(var i=0; i<4; i++){
            s += arr[randomInt(0, arr.length-1)];
        }
        console.log(s);
    
        function randomInt(m, n){
            return parseInt(Math.random() * (n-m+1) + m);
        }
    

    9. 常用方法

    字符串的切片

    • substring(start, stop)
      • 不能是负数
          var s = "abcca";
          console.log(s.substring(0, 3));  //abc
      
    • substr(start, len)
      • 参数2: 从start开始切到的字符串的长度
          var s = "abcca";
          console.log(s.substr(1, 2));  //bc
      
    • slice(start, stop)
      • 唯一的区别在于,这里的下标允许负数
          var s = "abcca";
          console.log(s.slice(-2, -1));  //c
      

    大小写转换

    • toUpperCase
    • toLowerCase
        var s = "abcca";
        console.log(s.toUpperCase());  //ABCCA
        console.log(s.toLowerCase());  //abcca
    

    去除字符串的首尾空白字符

    • trim()
        var s = "\n       abcca       ddddad     \t";
        console.log("--" + s.trim() + "---");  //--abcca       ddddad---
    
    • search(参数支持正则)
      • 查找——查找参数在字符串中出现的位置
    • match(字符串或正则)
      • 找出满足字符串或正则的子字符串,通过数组访问
    • replace(old, new)
      • 用new去把old给替换掉
    • split(切割用的字符串)
      • 正则表达式更加的强大

    10. 数学对象

    • Math.PI
    • Math.E //自然对数2.7....
    • Math.pow(num, m) //求次方
    • Math.abs(-num) //绝对值
    • Math.sqrt(num) //平方根
    • Math.pow(num, 1/3) //num的开次方。
    • js中用到角度的,一定是弧度,不是角度
    • CSS中一般都是用角度,JS是弧度
    • 360° == 2pi
    • 180° == pi
        function toRadian(deg){  //转弧度
            return deg / 180 * Math.PI;
        }
        function toDegree(red){   //转角度
            return red / Math.PI * 180;
        }
    

    11. 时间对象

    • 用一个整数来表示一个具体的时间点
    • 9435890348590 毫秒值 1970 1 1 0 0 0
        //如何知道某年某月一共多少天
        function daysOfMonth(year, month){
            return new Date(year, month, 0).getDate();
        }
        console.log(daysOfMonth(2016, 12));   //31
    

    相关文章

      网友评论

          本文标题:js_继承及原型链等(四)

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