JavaScript--高级---1

1.工厂模式和自定义构造函数的区别

工厂模式:
* 函数名是小写
* 有new,
* 有返回值
* new之后的对象是当前的对象
* 直接调用函数就可以创建对象

* 自定义构造函数:
* 函数名是大写(首字母)
* 没有new
* 没有返回值
* this是当前的对象
* 通过new的方式来创建对象

2.实例对象和构造函数之间的关系:

 1. 实例对象是通过构造函数来创建的---创建的过程叫实例化
 2.如何判断对象是不是这个数据类型?
  1) 通过构造器的方式 实例对象.构造器==构造函数名字
   2) 对象 instanceof 构造函数名字

3.原型

实例对象中有__proto__这个属性,叫原型,也是一个对象,这个属性是给浏览器使用,不是标准的属性----->__proto__----->可以叫原型对象
构造函数中有prototype这个属性,叫原型,也是一个对象,这个属性是给程序员使用,是标准的属性------>prototype--->可以叫原型对象

* 实例对象的__proto__和构造函数中的prototype相等----->true
* 又因为实例对象是通过构造函数来创建的,构造函数中有原型对象prototype
* 实例对象的__proto__指向了构造函数的原型对象prototype

4.通过原型来添加方法,解决数据共享,节省内存空间

function Person(name,age) {
      this.name=name;
      this.age=age;
    }
    //通过原型来添加方法,解决数据共享,节省内存空间
    Person.prototype.eat=function () {
      console.log("吃凉菜");
    };

    var p1=new Person("小明",20);
    var p2=new Person("小红",30);
    console.log(p1.eat==p2.eat);//true

    console.dir(p1);
    console.dir(p2);

5.构造函数、实例对象和原型对象的关系

总结:

  构造函数可以实例化对象。

  构造函数中有一个属性叫prototype,是构造函数的原型对象。
  构造函数的原型对象(prototype)中有一个constructor构造器,这个构造器指向的就是自己所在的原型对象所在的构造函数。
  实例对象的原型对象(__proto__)指向的是该构造函数的原型对象。
  构造函数的原型对象(prototype)中的方法是可以被实例对象直接访问的。

 6.继承

1)js中通过原型来实现继承(相同的代码太多,造成了代码的冗余(重复的代码)

function Person(name,age,sex) {
      this.name=name;
      this.sex=sex;
      this.age=age;
    }
    Person.prototype.eat=function () {
      console.log("人可以吃东西");
    };
    Person.prototype.sleep=function () {
      console.log("人在睡觉");
    };
    Person.prototype.play=function () {
      console.log("生活就是不一样的玩法而已");
    };


    function Student(score) {
      this.score=score;
    }
    //改变学生的原型的指向即可==========>学生和人已经发生关系
    Student.prototype=new Person("小明",10,"男");
    Student.prototype.study=function () {
      console.log("学习很累很累的哦.");
    };

    //相同的代码太多,造成了代码的冗余(重复的代码)

    var stu=new Student(100);
    console.log(stu.name);
    console.log(stu.age);
    console.log(stu.sex);
    stu.eat();
    stu.play();
    stu.sleep();
    console.log("下面的是学生对象中自己有的");
    console.log(stu.score);
    stu.study();

 2)借用构造函数(父级类别中的方法不能继承,解决了属性问题

function Person(name, age, sex, weight) {
      this.name = name;
      this.age = age;
      this.sex = sex;
      this.weight = weight;
    }
    Person.prototype.sayHi = function () {
      console.log("您好");
    };
    function Student(name,age,sex,weight,score) {
      //借用构造函数
      Person.call(this,name,age,sex,weight);
      this.score = score;
    }
    var stu1 = new Student("小明",10,"男","10kg","100");
    console.log(stu1.name, stu1.age, stu1.sex, stu1.weight, stu1.score);

    var stu2 = new Student("小红",20,"女","20kg","120");
    console.log(stu2.name, stu2.age, stu2.sex, stu2.weight, stu2.score);

    var stu3 = new Student("小丽",30,"妖","30kg","130");
    console.log(stu3.name, stu3.age, stu3.sex, stu3.weight, stu3.score);

 3)组合继承:原型继承+借用构造函数继承(既能解决属性问题,又能解决方法问题

function Person(name,age,sex) {
      this.name=name;
      this.age=age;
      this.sex=sex;
    }
    Person.prototype.sayHi=function () {
      console.log("阿涅哈斯诶呦");
    };
    function Student(name,age,sex,score) {
      //借用构造函数:属性值重复的问题
      Person.call(this,name,age,sex);
      this.score=score;
    }
    //改变原型指向----继承
    Student.prototype=new Person();//不传值
    Student.prototype.eat=function () {
      console.log("吃东西");
    };
    var stu=new Student("小黑",20,"男","100分");
    console.log(stu.name,stu.age,stu.sex,stu.score);
    stu.sayHi();
    stu.eat();
    var stu2=new Student("小黑黑",200,"男人","1010分");
    console.log(stu2.name,stu2.age,stu2.sex,stu2.score);
    stu2.sayHi();
    stu2.eat();

4)拷贝继承(就是把对象中需要共享的属性或者犯法,直接遍历的方式复制到另一个对象中

function Person() {
    }
    Person.prototype.age=10;
    Person.prototype.sex="男";
    Person.prototype.height=100;
    Person.prototype.play=function () {
      console.log("玩的好开心");
    };
    var obj2={};
    //Person的构造中有原型prototype,prototype就是一个对象,那么里面,age,sex,height,play都是该对象中的属性或者方法

    for(var key in Person.prototype){
      obj2[key]=Person.prototype[key];
    }
    console.dir(obj2);
    obj2.play();

 7.函数中的this的指向

普通函数中的this是谁?-----window
对象.方法中的this是谁?----当前的实例对象
定时器方法中的this是谁?----window
构造函数中的this是谁?-----实例对象
原型对象方法中的this是谁?---实例对象

 8.闭包

闭包:函数A中有一个函数B,函数B中可以访问函数A中的变量或者数据,此时形成闭包。
闭包的模式:函数模式(里面的返回作为返回值),对象模式(里面的对象作为返回值)。
闭包的作用:缓存数据---是优点也是缺点。

闭包的作用缓存数据:只要是想把数据保存起来,就把这个数据放在闭包中(就是在外层函数和里层函数的中间)
正因为闭包的出现缓存了数据,那么函数中的变量就没有得到及时的释放,,延长作用域了。

//函数模式的闭包
    function f1() {
      var num = 10;
      return function () {
        console.log(num);
      }
    }
    var ff=f1();
    ff();
    //对象模式的闭包
    function f3() {
      return {
        age:100,
        getAge:function () {
          console.log(this.age);
        }
      }
    }

产生相同的随机数,函数调用多次

function showRandom2() {
     var random= parseInt(Math.random()*10+1);//产生一次随机数
     return function () {
       console.log(random);//每次输出的都是最开始产生的随机数字的值
     }
   }
   var ff=showRandom2();//调用一次
   ff();
   ff();
   ff();

9.沙箱

沙箱:环境,黑盒,---在虚拟的世界中,模拟真实世界的场景,做实验,实验的结果和真实世界的结果一样,但是不会影响真实的世界。

//沙箱
(function (x) {
      //局部变量
      var num=1000;
      console.log(num);//1000
    }(100));

    //全局变量
    var num=10000;
    console.log(num);//10000
//沙箱可以解决命名冲突的问题
    (function () {
      var x=10;
      function f1() {

      }
    }());

    (function () {
      var x=10;
      function f1() {

      }
    }());

10.call()、apply()、bind()的区别

11.浅拷贝

 浅拷贝:拷贝就是复制,就相当于把一个对象中的所有的内容,复制一份给另一个对象,直接复制,或者说,就是把一个对象的地址给了另一个对象,他们指向相同,两个对象之间有共同的属性或者方法,都可以使用。

var obj1={
      age:10,
      sex:"男",
      car:["奔驰","宝马","特斯拉","奥拓"]
    };
    //另一个对象
    var obj2={};
    
    //写一个函数,作用:把一个对象的属性复制到另一个对象中,浅拷贝
    //把a对象中的所有的属性复制到对象b中
    function extend(a,b) {
      for(var key in a){
        b[key]=a[key];
      }
    }
    extend(obj1,obj2);
    console.dir(obj2);//开始的时候这个对象是空对象
    console.dir(obj1);//有属性

12. 深拷贝

深拷贝:拷贝还是复制,深:把一个对象中所有的属性或者方法,一个一个的找到.并且在另一个对象中开辟相应的空间,一个一个的存储到另一个对象中。

var obj1={
      age:10,
      sex:"男",
      car:["奔驰","宝马","特斯拉","奥拓"],
      dog:{
        name:"大黄",
        age:5,
        color:"黑白色"
      }
    };

    var obj2={};//空对象
    //通过函数实现,把对象a中的所有的数据深拷贝到对象b中
    function extend(a,b) {
      for(var key in a){
        //先获取a对象中每个属性的值
        var item=a[key];
        //判断这个属性的值是不是数组
        if(item instanceof Array){
          //如果是数组,那么在b对象中添加一个新的属性,并且这个属性值也是数组
          b[key]=[];
          //调用这个方法,把a对象中这个数组的属性值一个一个的复制到b对象的这个数组属性中
          extend(item,b[key]);
        }else if(item instanceof Object){//判断这个值是不是对象类型的
     //如果是对象类型的,那么在b对象中添加一个属性,是一个空对象
          b[key]={};
          //再次调用这个函数,把a对象中的属性对象的值一个一个的复制到b对象的这个属性对象中
          extend(item,b[key]);
        }else{
          //如果值是普通的数据,直接复制到b对象的这个属性中
          b[key]=item;
        }
      }
    }

    extend(obj1,obj2);
    console.dir(obj1);
    console.dir(obj2);

13.正则表达式

正则表达式:也叫规则表达式,按照一定的规则组成的一个表达式,这个表达式的作用主要是匹配字符串的。

正则表达式的作用:匹配字符串的。
正则表达式的组成:是由元字符或者是限定符组成的一个式子。

规则:

. 除了 以外的任意一个单个字符
 [] 范围
 () 分组,提升优先级
 | 或者
 * 0-多次
 + 1-多次
? 0-1次
{0,} 和*一样
 {1,} 和+
 {0,1} 和?
 d 数字中的一个
 D 非数字
 s 空白符
 S 非空白符
 W 特殊符号
 w 非特殊符号 _
 ^ 取反,以什么开始
 $ 以什么结束
  单词边界

 14.伪数组和数组的区别

真数组的长度是可变的
伪数组的长度不可变
真数组可以使用数组中的方法
伪数组不可以使用数组中的方法

原文地址:https://www.cnblogs.com/lax-17xu/p/12444982.html