来看一看这个面试题

202 阅读2分钟

1、实现一个阶乘

function factorial (n){
 return n>1 ? factorial(n-1)*n : 1;
}

2、说一下深拷贝和浅拷贝

浅拷贝:

对于字符串等基本数据类型的数据来说,浅拷贝就是对值得复制拷贝。

对于对象等引用类型来说,浅拷贝是对对象的地址复制,并没有开辟新的栈。复制的结果就是两个对象指向同一个地址,修改一个对象的属性,另外一个对象的属性也会跟着改变。

深拷贝

深拷贝是开辟新的栈,两个对象对应不同的地址,修改一个对象的属性,不会修改另外一个对象的属性。

实现深拷贝:

function deepCopy(obj) {
  var objArray = Array.isArray(obj) ? [] : {};
  if(obj && typeof obj ==="object"){
    for(key in obj){
      if(obj.hasOwnProperty(key)){
        //如果obj的子元素是对象,递归操作
        if(obj[key] && typeof obj[key] ==="object"){
          objArray[key] = deepCopy(obj[key]);
        }else{
          //如果不是直接赋值
          objArray[key] = obj[key]
        }
      }
    }
  }
  return objArray;
}

var s1 = {
  num:10
}

var objs=deepCopy(s1);
objs.num=11;
console.log(s1.num);
console.log(objs.num);

jquery的extend方法也可以实现深拷贝

JQuery.extend([deep],target,object1,[objectN])
var obj1 = {
  num:100
}
var obj2=$.extend(true,{},obj1);
obj2.num=11;
console.log(obj1.num);
console.log(obj2.num);

通过JSON的序列化和反序列化实现

var test = {
  name:{
    first:'刘',
    second:'张'
  },
  age:32,
  friend:['老王','老李','老孙']
}

var result = JSON.parse(JSON.stringify(test));
result.age=50;
result.friend.push('小张');
console.log(test);
console.log(result);

3、写一个弹窗插件

要求拓展性强,简洁易用。

js原生插件的几种常用写法

一、工厂模式

工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程。但是缺点是,每次调用一次,就需要实例化一次,调用次数多了就会很占用内存。

function createPerson(name, age, job) {
  var o = new object();
  o.name = name;
  o.age = age;
  o.job = job;
  o.sayName = function (){
    alert(this.name);
  }
  return o;
}

var person = createPerson("老王",30,'Doctor')

二、自动执行函数

var createPerson=(function () {
  function sayName(name) {
    console.log(name);
  }
  return{
    log:sayName
  }
})();
createPerson.log("老王")

三、原型模式

我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。

function Person() {
  
}
Person.prototype.name = '老王';
Person.prototype.sayName = function () {
  console.log(this.name);
}

var personOne = new Person();
personOne.sayName() 


四、组合使用构造函数模式和原型模式

构造函数模式用于定义实例属性,原型模式用于定义方法和共享属性。每个实例都有自己的一份实例属性的副本,但同时又共享着对方法的引用,最大限度的节省了内存。

function Person(name, age, job) {
  this.name = name;
  this.age = age;
  this.job = job;
}

Person.prototype = {
  constructor : Person,
  sayName : function () {
    console.log(this.name);
  }
}

var personOne = new Person('老王', 30, 'Doctor');
personOne.sayName()

JQuery插件写法

一、对JQuery自身的扩展插件

对JQuery自身的方法库进行扩展。在使用的时候通过$.FunName()的方式直接使用。

//创建
$.extend({
  insertHello:function (dom) {
    $(dom).html("Hello World")
  }
})
//引用
$(document).ready(function () {
  $.insertHello('#hello')
})

二、对HTML标记或页面元素进行扩展

使用这种插件的拓展方式,需要首先引用经过JQuery包装的页面元素,例如$("#someId").Method().

(function ($) {
  $.fn.setModelUI = function (options) {
    let defaults = {
      time : 100 ,
      name : "老王",
      age  : 30
    }
    var options = $.extend(defaults, options);
    this.each(function () {
      console.log(options.name);
    })
  }
})(jQuery);

$(document).ready(function () {
  $(".indexheader").setModelUI({name:"老李"});
})

4、说一下本地缓存

cookie: 储存大小4K,存储的是字符串,没有自己的读写方法。安全性相对较低。

sessionStorage:存储特定于某个会话的数据,也就是说该数据只能保持到浏览器关闭。存储大小为5M,有自己的存储方法(setItem,getItem),存储的是对象,以键值对的方式存储。

localStorage:永久保存客户端数据,存储大小和方式与sessionStorage相同。

5、React热加载

后续更新。。。。

6、$extend和$fn的区别


7、深入的说一下addEventListener()和removeEventLister()


8、同步和异步的区别


9、React的虚拟DOM