通过在牛客网答题总结的前端考题(三)JavaScript

1. 执行环境及作用域

  • 执行环境定义了变量或函数有权访问的其他数据,决定它们各自的行为,每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和对象也都保存在对象中。
  • 每个函数都有自己的执行环境,当执行流进入一个函数时,函数的环境就会被推进一个环境栈中,函数执行后,栈将其环境推出,把控制权返回给之前的执行环境。

2. 原型链:通过将一个类型的实例赋值给另一个构造函数的原型实现。

继承:

父类:

// 定义一个动物类
function Animal (name) {
  // 属性
  this.name = name || 'Animal';
  // 实例方法
  this.sleep = function(){
    console.log(this.name + '正在睡觉!');
  }
}
// 原型方法
Animal.prototype.eat = function(food) {
  console.log(this.name + '正在吃:' + food);
};

  • 原型链继承:可在不必预先定义构造函数的情况下继承,将父类的实例作为子类的原型
    function Cat(){ 
    }
    Cat.prototype = new Animal();
    Cat.prototype.name = 'cat';
    
    // Test Code
    var cat = new Cat();
    console.log(cat.name);
    console.log(cat.eat('fish'));
    console.log(cat.sleep());
    console.log(cat instanceof Animal); //true 
    console.log(cat instanceof Cat); //true
  • 寄生式继承:类似原型式继承,基于某个对象或某些信息创建一个对象,然后增强对象,最后返回对象。
  • 构造继承:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类
    function Cat(name){
      Animal.call(this);
      this.name = name || 'Tom';
    }
    
    // Test Code
    var cat = new Cat();
    console.log(cat.name);
    console.log(cat.sleep());
    console.log(cat instanceof Animal); // false
    console.log(cat instanceof Cat); // true
  • 实例继承:为父类实例添加新特性,作为子类返回
    function Cat(name){
      var instance = new Animal();
      instance.name = name || 'Tom';
      return instance;
    }
    
    // Test Code
    var cat = new Cat();
    console.log(cat.name);
    console.log(cat.sleep());
    console.log(cat instanceof Animal); // true
    console.log(cat instanceof Cat); // false
  • 拷贝继承:
    function Cat(name){
      var animal = new Animal();
      for(var p in animal){
        Cat.prototype[p] = animal[p];
      }
      Cat.prototype.name = name || 'Tom';
    }
    
    // Test Code
    var cat = new Cat();
    console.log(cat.name);
    console.log(cat.sleep());
    console.log(cat instanceof Animal); // false
    console.log(cat instanceof Cat); // true
  • 组合继承:通过调用父类构造函数,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用。
    function Cat(name){
      Animal.call(this);
      this.name = name || 'Tom';
    }
    Cat.prototype = new Animal();
    Cat.prototype.constructor = Cat;
    
    // Test Code
    var cat = new Cat();
    console.log(cat.name);
    console.log(cat.sleep());
    console.log(cat instanceof Animal); // true
    console.log(cat instanceof Cat); // true
  • 寄生组合继承:通过寄生的方式,砍掉父类的实例属性,这样,在调用两次弗雷德构造的时候,就不会初始化两次实例方法/属性,避免组合继承的缺点。
    function Cat(name){
      Animal.call(this);
      this.name = name || 'Tom';
    }
    (function(){
      // 创建一个没有实例方法的类
      var Super = function(){};
      Super.prototype = Animal.prototype;
      //将实例作为子类的原型
      Cat.prototype = new Super();
    })();
    
    // Test Code
    var cat = new Cat();
    console.log(cat.name);
    console.log(cat.sleep());
    console.log(cat instanceof Animal); // true
    console.log(cat instanceof Cat); //true
    
    Cat.prototype.constructor = Cat; // 需要修复下构造函数
3. 创建对象:
  • 工厂模式:抽象了创建具体对象的过程,对对象添加属性、方法。然后返回对象,可创建多个相似对象,不能解决对象识别问题。
  • 构造函数模式:可以创建自定义引用类型,可以像创建内容对象实例一样使用new操作符。成员不可复用。
  • 原型模式:使用构造函数的prototype属性来指定那些应该共享的属性和方法。创建的每个函数都有一个prototype属性,这个属性是一个指针,指向一个对象。不必再构造函数中定义对象实例的信息,而可以将这些信息直接添加到原型对象中。
4. 闭包:有权访问另一个函数作用域中的变量函数。创建方式:在函数内部创建另一个函数。 闭包只能取得包含函数中任何变量的最后一个值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值