让前端飞Web前端之路JavaScript 进阶营

前端常见面试题(二十二)@郝晨光

2019-08-15  本文已影响47人  郝晨光

vw、vh、rem、em、px的区别


前端安全:xss攻击和CSRF攻击

http和https的区别


优雅降级和逐渐增强


什么是堆和栈


什么是BFC


什么是闭包,闭包的优缺点,内存泄露怎么处理,闭包的使用场景


内存泄露


将多维数组转化为一维数组


JS继承的方法及优缺点

  1. 原型链继承

    • function Parent() {
          this.name = 'parent'
      }
      Parent.prototype.sayName = function() {
          alert(this.name)
      }
      
      function Child() {
          this.age = 20;
      }
      Child.prototype = new Parent(); // 改造子类构造函数的原型,使其指向父类的实例。
      let child = new Child();
      child.name; // parent
      child.sayName; // alert(parent);
      child.age;  // 20
      
    • 通过改造子类的原型prototype,使其指向父类的实例,达到继承父类所有属性和方法的效果。

    • 优点:父类的方法也可以达到复用

    • 缺点:父类的属性也达到了复用,子类实例没有属于自己的属性(如上例中的name属性)

  2. 构造函数借用继承

    • function Parent(name) {
          this.name = name;
      }
      Parent.prototype.sayName = function() {
          alert(this.name);
      }
      
      function Child(name, age) {
          Parent.call(this, name); // 通过call或者apply的特性实现将父类的属性复用
          this.age = age;
      }
      Child.prototype.sayAge = function() {
          alert(this.age);
      }
      
      let child = new Child('child', 24);
      child.name; // child
      child.age; // 24
      child.sayName(); // error
      child.sayAge(); // alert(child)
      
    • 通过call和apply改变this指向并且调用函数的特性,实现父类的属性复用。

    • 优点:可以达到父类的属性复用,并且可以定制子类自己的属性值。

    • 缺点:父类上的方法没有实现复用

  3. 组合继承

    • function Parent(name) {
          this.name = name;
      }
      Parent.prototype.sayName = function() {
          alert(this.name);
      }
      
      function Child(name, age) {
          Parent.call(this, name); // 通过call或者apply的特性实现将父类的属性复用
          this.age = age;
      }
      Child.prototype = new Parent(); // 改造子类构造函数的原型,使其指向父类的实例。
      Child.prototype.sayAge = function() {
          alert(this.age);
      }
      
      let child = new Child('child', 24);
      child.name; // child
      child.age; // 24
      child.sayName(); // alert(child)
      child.sayAge(); // alert(24)
      
    • 组合继承,其实就是将原型链继承和构造函数借用继承组合到一块,结合他们之间的优点,使得既可以继承父类的方法,又可以在子类上继承父类的属性并定制。

    • 优点:结合了原型链继承和构造函数借用继承的优点,既继承了父类的方法,又继承了父类的属性,并可以定制。

    • 缺点:父类的构造函数被调用了两次,在子类的构造函数内调用一次,在子类的prototype上调用一次,并且子类的prototype上的属性会被覆盖掉,造成内存浪费。

  4. 原型式继承

    • function Parent(name) {
          this.name = name;
      }
      Parent.prototype.sayName = function() {
          alert(this.name);
      }
      
      function createObject(obj) {
          function F() {};
          F.prototype = obj;
          return new F();
      }
      
      let parent = new Parent('parent');
      let child = createObject(parent);
      child.name; // parent;
      child.sayName(); // alert(parent)
      
    • 原型式继承是通过借助临时的构造函数,将原有的对象的属性和方法进行浅拷贝,然后赋予新的对象,实现继承。通过ES5新增的Objet.create也可以实现。

    • 优点:好像没什么优点

    • 缺点:缺点和原型链继承一样,只能实现属性和方法的复用,子类没有属于自己的属性,没有可定制性。

  5. 寄生式继承

    • function Parent(name) {
          this.name = name;
      }
      Parent.prototype.sayName = function() {
          alert(this.name);
      }
      
      function createObject(obj) {
          function F() {};
          F.prototype = obj;
          return new F();
      }
      
      function Child(name, age) {
          let parent = new Parent(name);
          let result = createObject(parent);
          result.age = age;
          return result;
      }
      
      let child = Child('child', 24);
      child.sayName(); // alert(child)
      
    • 寄生式继承是将原型式继承封装成为一个函数,并且进行参数传递,实现子类继承父类的属性和方法,并且可以定制属性。

    • 优点:子类可以继承父类的属性和方法,并且可以定制属性

    • 缺点:子类不是通过new关键字调用的,所以没有属于自己的方法,如果要创建子类的方法,那就是每一个子类都得重新创建一遍,不能达到子类的方法复用。

  6. 组合寄生式继承

    • function Parent(name) {
          this.name = name;
      }
      Parent.prototype.sayName = function() {
          alert(this.name);
      }
      
      function Child(name, age) {
          Parent.call(this, name);
          this.age = age;
      }
      Child.prototype = Object.create(Parent.prototype);
      Child.prototype.constructor = Child;
      Child.prototype.sayAge = function() {
          alert(this.age);
      }
      
      let child = new Child('child', 24);
      child.sayName(); // alert(child)
      child.sayAge(); // alert(24)
      
    • 组合寄生式继承,结合了组合继承的优点,并结合了寄生式继承的优点,目前为止完美的继承方式。

    • 优点:可以继承父类的属性和方法,并且可以定制,最主要的是对于父类的构造函数只需要调用一次。并且可以正常的使用intanceof和isPrototypeOf,原型链保持正常。

    • 缺点:好像没什么缺点


结言
感谢您的查阅,本文由郝晨光整理并总结,代码冗余或者有错误的地方望不吝赐教;菜鸟一枚,请多关照
上一篇 下一篇

猜你喜欢

热点阅读