面向对象基础三

一、复习面向对象

* 原型:
    * 每个实例对象中都有一个属性__proto__,是原型,浏览器使用的,不标准的属性
    * 每个构造函数中都有一个属性prototype,是原型,程序员使用的,
    * 面向对象和面向过程都是编程思想
    * 面向对象注重的是结果,面向过程注重的是过程
    * 面向对象的特性:封装,继承,多态
    * 继承:
    * 1.通过原型实现继承,改变原型的指向,属性在初始化的时候就已经固定了,如果是多个对象实例化,那么每个实例对象的属性的值在初始化的时候都是一样的
    * 2.借用构造函数继承,不能继承方法
    * 3.组合继承,可以解决属性和方法的继承的问题
    * 4.拷贝继承,就是把一个对象中的原型中的所有的属性和方法复制一份给另一个对象
    *
    *
    * 创建对象的三种方式
    * 1. 字面量的方式
    * 2. 调用系统的构造函数

    * 3. 自定义构造函数

* 原型链:实例对象和原型对象之间的关系,主要是通过__proto__和prototype来联系
    *
    * 原型的指向是可以改变,所以,js中是通过改变原型来实现继承
    *
    *
    * 原型的作用:
    * 实现数据共享,继承, 都是为了节省内存空间
    * 如果属性和方法都需要共享,那么就把属性和方法添加到原型中
    *
    *
    * 函数中的this的指向
    *
    * 普通的函数中this是window
    * 构造函数中的this,构造函数一般都是创建实例对象使用的,是通过new关键字,构造函数也是函数
    * 构造函数中的this是实例对象
    * 方法中的this是实例对象
    * 原型中的方法中的this是实例对象
    * 定时器中的this是window
    *
    * 函数是对象,构造函数也是函数,也是对象
    * 对象是不是函数呢?不一定
    *
    * 对象中有__proto__
    * 函数中有prototype
    *

    * Math是对象,但不是函数

二、面向对象三介绍

* apply和call方法的使用
    * bind方法的使用---------这三个方法是重点,
    *
    *
    * 函数中的几个成员的介绍----了解
    * 高阶函数(函数作为参数,函数作为返回值)
    * 函数作为参数使用的例子
    * 函数作为返回值使用的例子
    * 作用域,作用域链,预解析
    * 闭包--------重点,作用,优点,缺点
    * 闭包的案例---重点
    *
    * 沙箱---概念,作用,以后该怎么办
    *

    * 递归---重点,难,难在应用,为了遍历

三、apply和call的使用

都可以改变this的指向,都可以让函数或者是方法调用。传入参数和函数自己调用写法不一样但是效果是一样的。实例对象调用方法在实例对象中存在或者是原形对象中都没有就报错。

apply和call方法实际上并不在函数这个实例对象中,而是在Function的prototype中。

    function f1() {
      console.log(this+":====>调用了");
    }
    //f1是函数,f1也是对象
    console.dir(f1);
    //对象调用方法,说明,该对象中有这个方法
    f1.apply();
    f1.call();
    console.log(f1.__proto__==Function.prototype);//ture
    //所有的函数都是Function的实例对象
    console.log(Function.prototype);//Function的 prototype是 :ƒ () { [native code] }
    console.dir(Function);
    //apply和call方法实际上并不在函数这个实例对象中,而是在Function的prototype中

 * apply的使用语法
    * 函数名字.apply(对象,[参数1,参数2,...]);
    * 方法名字.apply(对象,[参数1,参数2,...]);
    * call的使用语法
    * 函数名字.call(对象,参数1,参数2,...);
    * 方法名字.call(对象,参数1,参数2,...);
    *本来函数的指向都是window , 但是这两个方法改变了指向。
    * 作用:改变this的指向
    * 不同的地方:参数传递的方式是不一样的
    *
    * 只要是想使用别的对象的方法,并且希望这个方法是当前对象的,那么就可以使用apply或者是call的方法改变this的指向

function Person(age,sex) {
      this.age=age;
      this.sex=sex;
    }
    //通过原型添加方法
    Person.prototype.sayHi=function (x,y) {
      console.log("您好啊:"+this.sex);
      return 1000;
    };
    var per=new Person(10,"男");
    per.sayHi();


    console.log("==============");
    function Student(name,sex) {
      this.name=name;
      this.sex=sex;
    }
    var stu=new Student("小明","人妖");
    var r1=per.sayHi.apply(stu,[10,20]);
    var r2=per.sayHi.call(stu,10,20);


    console.log(r1);
    console.log(r2);

三、bind方法

1.是复制一份,把参数传递到指定对象中。

使用方法:

 * 函数名字.bind(对象,参数1,参数2,...);---->返回值是复制之后的这个函数
    * 方法名字.bind(对象,参数1,参数2,...);---->返回值是复制之后的这个方法
    * 函数名字:apply(对象,参数1,参数2...)
    * 方法,名字.call(对象,参数1,参数2...)

 function Person(age) {
      this.age=age;
    }
    Person.prototype.play=function () {
      console.log(this+"====>"+this.age);
    };


    function Student(age) {
      this.age=age;
    }
    var per=new Person(10);
    var stu=new Student(20);
    //复制了一份
    var ff=per.play.bind(stu);

    ff();

2.bind的方法案例:

通过对象调用方法产生随机数

function ShowRandom() {
      //1-10的随机数
      this.number=parseInt(Math.random()*10+1);
    }
    //添加原型方法
    ShowRandom.prototype.show1=function () {
      //改变了定时器中的this的指向了,本来应该是window,现在是实例对象了
      window.setInterval(this.show2.bind(this),1000);//第一个this 代表着window对象。,当加上了bind之后,再加上this  show中的this的指向变了。
      
      //thisAgs 是函数或者方法。
//    window.setInterval(function(){
//    console.log(this);
//    })
    };
    //添加原型方法
    ShowRandom.prototype.show2=function () {
      //显示随机数--
      console.log(this.number);
    };
    //实例对象
    var sr=new ShowRandom();
    //调用方法,输出随机数字
    //调用这个方法一次,可以不停的产生随机数字
    sr.show1();
    
    ShowRandom.prototype.show1=function(){
    function f1() {
    console.log(this);
    }
    window.setInterval(f1.bind(this),1000);

    }

四、函数中的基本知识

1.函数中的几个成员:name arguments  length caller

//函数中有一个name属性----->函数的名字,name属性是只读的,不能修改
    //函数中有一个arguments属性--->实参的个数
    //函数中有一个length属性---->函数定义的时候形参的个数
    //函数中有一个caller属性---->调用(f1函数在f2函数中调用的,所以,此时调用者就是f2)
    function f1(x,y) {
      console.log(f1.name);
      console.log(f1.arguments.length);
      console.log(f1.length);
      console.log(f1.caller);//调用者
    }
    function f2() {
      console.log("f2函数的代码");
      f1(1,2);
    }
    f2();

2.函数作为参数使用

 function f1(fn) {
        console.log("f1的函数");
        fn();//此时fn当成是一个函数来使用的
      }
    //fn是参数,最后作为函数使用了,函数是可以作为参数使用
   //传入匿名函数
      f1(function () {
        console.log("我是匿名函数");
      });
   //命名函数
      function f2() {
        console.log("f2的函数");
      }
      f1(f2);
  //函数作为参数的时候,如果是命名函数,那么只传入命名函数的名字,没有括号
      function f1(fn) {
        setInterval(function () {
          console.log("定时器开始");
          fn();
          console.log("定时器结束");
        },1000);
      }
      f1(function () {
        console.log("好困啊,好累啊,就是想睡觉");
      });

3.函数作为返回值使用

function f1() {
            console.log("f1函数开始");
            return function () {
              console.log("我是函数,但是此时是作为返回值使用的");
            }
      
          }
      
          var ff=f1();//由于函数的返回值是函数,赋值给一个变量的时候,变量本身就是一个函数,额可以调用

          ff();

4.Object.prototype.toString()用法

用于获取某个对象的类型是不是你传入的类型,这个方法中的toString归Object所有。如何让它适应其他类型的数据需要改变this 的指向。使用call方法,这个方法也是Object所有的。由于 转换结果是string类型需要加上双引号

 判断这个对象是不是某个类型的
          console.log(obj instanceof Object);
          //获取某个对象的数据类型的样子

         Object.prototype.toString.call(对象);//此时得到的就是这个对象的类型的样子

      //借用Object的方法toString 输出的数组的数据类型,调用了call说明这个对象属于数组的。 [object Array]

          console.log(Object.prototype.toString.call([]));

//这个toString对象现在数据Date类型。
    console.log(Object.prototype.toString.call(new Date()));

//判断这个对象和传入的类型是不是同一个类型
    function getFunc(type) {
      return function (obj) {
        return Object.prototype.toString.call(obj) === type;
      }
    }


    var ff = getFunc("[object Array]");
    var result = ff([10, 20, 30]);
    console.log(result);
    //是true;
    var ff1 = getFunc("[object Object]");
    var dt = new Date();
    var result1 = ff1(dt);//"[object Date]"
    console.log(result1);

5.函数作为参数的案例

知识点:sort() 方法用于对数组的元素进行排序,并返回数组。默认排序顺序是根据字符串Unicode码点。
语法:arrayObject.sort(sortby);参数sortby可选。规定排序顺序。必须是函数。
注:如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,说得更精确点,是按照字符编码的顺序进行排序。要实现这一点,首先应把数组的元素都转换成字符串(如有必要),以便进行比较。*/

 var arr = [1, 100, 20, 200, 40, 50, 120, 10];
    //排序---函数作为参数使用,匿名函数作为sort方法的参数使用,那么此时的匿名函数中有两个参数,
    arr.sort(function (obj1,obj2) {
      if(obj1>obj2){
        return -1;
      }else if(obj1==obj2){
        return 0;
      }else{
        return 1;
      }
    });
    console.log(arr);


    var arr1=["acdef","abcd","bcedf","bced"];
    arr1.sort(function (a,b) {
      if(a>b){
        return 1;
      }else if(a==b){
        return 0;
      }else{
        return -1;
      }
    });
    console.log(arr1);


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值