美文网首页
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