JS基础知识(覆盖JS基础面试题)

简介: 总结一些前端基础的知识,有些知识可能在前端面试的时候会问到,所以做个记录,也有助于其他人查看,如果有什么问题,可以指出,会积极修正。

总结一些前端基础的知识,有些知识可能在前端面试的时候会问到,所以做个记录,也有助于其他人查看,如果有什么问题,可以指出,会积极修正。

变量类型和计算

JS中typeof的类型有哪些

    console.log(typeof undefined);  //undefined
    console.log(typeof 123);  //number
    console.log(typeof '123');  //string
    console.log(typeof true); //boolean
    console.log(typeof [1,2,3]);  //object
    console.log(typeof {"id": 11}); //object
    console.log(typeof null); //object
    console.log(typeof console.log);  //function
复制代码

类型转换

  • 显式类型转换
    • Number 函数
      • 数字:转换后还是数字
      • 字符串:如果可以被解析为数值,则为相应的数值,如果不能,则是 NaN,如果是空字符串那就是0
      • 布尔值:true为1,false为0
      • undefined:NaN
      • null:0
      • object:先执行valueOf,看是否能转换,如果不可以再执行toString,看是否可以转换,如果不可以报错
    • String 函数
      • 数字:转换成对应的字符串
      • 字符串:还是对应的字符串
      • 布尔值:true为'true',false为'false'
      • undefined:undefined
      • null:null
      • object:先执行toString,看是否能转换,如果不可以再执行valueOf,看是否可以转换,如果不可以报错
    • Boolean
      下面这几个是false,其他都是true
      • NaN
      • null
      • undefined
      • 0
      • ""
      • false
  • 隐式类型转换
    • 四则运算
    • 判断语句
  • 奇葩的类型转换面试题

465fb1b3cd4dea3fe0be07a087dc6867723ea566

何时使用==,何时使用===

除了obj.a == null以外,都用=====要用的时候一定要是已经定义的
obj.a == null 转换之后其实是 obj.a == null || obj.a == undefined

JS中有哪些内置函数

    Object
    Array
    Boolean
    Number
    String
    Function
    Date
    RegExp
    Error
复制代码

JS变量按照存储方式有哪些类型

  • 1.值类型
  • 2.引用类型(节省空间,公用内存块)

区别:值类型改变一个不会影响其他的,引用类型改变都改变,因为公用内存块

如何理解JSON

JSON是JS的一个对象,也是一种数据格式,JSON中的两个api如下

  1. 将JSON字符串转换成JSON对象 JSON.parse()
  2. 将JSON对象转换成JSON字符串 JSON.stringify()

使用Object.prototype.toString获取一个对象的类型

var toString = Object.prototype.toString;

toString.call(new Date); // [object Date]
toString.call(new String); // [object String]
toString.call(Math); // [object Math]
toString.call(/s/); // [object RegExp]
toString.call([]); // [object Array]

//Since JavaScript 1.8.5
toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]
复制代码

原型和原型链

原型的五条规则

  1. 所有的引用类型都可以自定义添加属性
  2. 所有的引用类型都有自己的隐式原型(proto
  3. 函数都有自己的显式原型(prototype)
  4. 所有的引用类型的隐式原型都指向对应构造函数的显示原型
  5. 使用引用类型的某个自定义属性时,如果没有这个属性,会去该引用类型的__proto__(也就是对应构造函数的prototype)中去找

8f6be6cfb534e104a1a6d769efed239b36c356b8

如何准确判断一个变量是数组类型

arr instanceof Array

instanceof判断一个引用类型是什么引用类型,是通过__proto__(隐式原型一层一层往上找,能否找到对应构造函数的prototype)

写一个原型链继承的例子

function Element(ele) {
  this.ele = document.getElementById(ele);
}

Element.prototype.html = function(val) {
  var ele = this.ele;
  if (val) {
    ele.innerHTML = val;
    return this;
  } else {
    return ele.innerHTML;
  }
};

Element.prototype.on = function(type, fn) {
  var ele = this.ele;
  ele.addEventListener(type, fn);
  return this;
}

var element = new Element('main');

element.html('hello').on('click', function() {
  alert('handleClick');
});
复制代码

描述new一个对象的过程

  1. 创建一个新对象
  2. this指向这个新对象
  3. 执行代码给this赋值
  4. return this
function Foo(name) {
  this.name = name;
  // return this;  // 本身会执行这一步
}

var f = new Foo('shiyanping');
复制代码

作用域及闭包

变量提升

以下两种情况会进行提升:

  1. 变量定义
  2. 函数说明

this几种不同的使用场景

  1. 在构造函数中使用(构造函数本身)
  2. 作为对象属性时使用(调用属性的对象)
  3. 作为普通函数时使用(window)
  4. call,apply,bind(执行的第一个参数)
var a = {
  name: 'A',
  fun: function() {
    console.log(this.name);
  }
};

a.fun();  //this === a
a.fun.call({ name: 'B' });  //this === { name: 'B' }
var fun1 = a.fun;
fun1(); //this === window
复制代码

创建10个a标签,点击每个弹出对应的序号

var i;
for (i = 0; i < 10; i++) {
  (function(i) {
    // 函数作用域
    var a = document.createElement('a');
    a.innerHTML = i + '<br>';
    a.addEventListener('click', function(e) {
      e.preventDefault();
      alert(i);
    });
    document.body.appendChild(a);
  })(i);
}
复制代码

如何理解作用域

  1. 自由变量
  2. 作用域链,及自由变量的查找,找不到逐级向上找
  3. 闭包的两个场景
    1. 函数作为变量传递
    2. 函数作为返回值

实际开发中闭包的应用

// 判断一个数字是否出现过
function isFirst() {
  var _list = [];
  return function(id) {
    if (_list.indexOf(id) >= 0) {
      return false;
    } else {
      _list.push(id);
      return true;
    }
  };
}

var first = isFirst();
first(10);
first(10);
first(20);
复制代码

单线程和异步

同步和异步的区别,分别列举一个同步和异步的例子

同步会阻塞代码,但是异步不会 alert是同步 setTimeout是异步

关于setTimeout的笔试题

console.log(1);
setTimeout(function() {
  console.log(2);
}, 0);
console.log(3);
setTimeout(function() {
  console.log(4);
}, 1000);
console.log(5);
// 输出结果:1,3,5,2,4
复制代码

前端使用异步的场景

  1. 定时任务:setTimeout,setInterval
  2. 网络请求:ajax请求,动态img加载
  3. 事件绑定

需要等待的情况下都需要异步,因为不会像同步一样阻塞

日期和Math

知识点:

日期

console.log(Date.now());  // 获取当前毫秒数
var dt = new Date();  // 获取当前时间
console.log(dt.getTime());  // 当前时间的毫秒数
console.log(dt.getFullYear());  //  年
console.log(dt.getMonth()+1); // 月(0-11)
console.log(dt.getDate());  // 日(0-31)
console.log(dt.getHours()); // 时(0-23)
console.log(dt.getMinutes()); // 分(0-59)
console.log(dt.getSeconds()); // 秒(0-59)
复制代码

Math

  • Math.random() - 返回 0 ~ 1 之间的随机数
  • Math.abs(x) - 返回数的绝对值
  • Math.ceil(x) - 向上取整
  • Math.floor(x) - 向下取整

常用的数组api

  • forEach(遍历所有元素)
var arr = ['a', 'b', 'c', 'd'];
arr.forEach(function (item, index) {
  console.log(item + ',' + index);
})
复制代码
  • map(对数组进行重新组装,生成新的数组)
// map,生成新数组,不改变原来数组的格式
var arr = ['a', 'b', 'c', 'd'];
var result = arr.map(function (item, index) {
  return index + '/' + item;
})
console.log(result);
复制代码
  • sort(对数组进行排序)
// sort, 会改变原来数组
var arr = [1, 23, 3, 4];
var result = arr.sort(function (a, b) {
  // 从小到大排序
  return a - b;

  // 从大到小排序
  // return b - a;
})
console.log(result);
复制代码
  • filter(过滤符合条件的元素)
var arr = [1, 2, 3, 4];
var result = arr.filter(function (item, index) {
  if (item < 3) {
    return true
  }
})
console.log(result);
复制代码
  • every(判断所有元素是否都符合要求)
var arr = [1, 2, 3, 4];
var result = arr.every(function (item, index) {
  if (item < 3) {
    return true
  }
})
console.log(result);   // false
复制代码
  • some(判断是否有至少一个元素符合条件)
var arr = [1, 2, 3, 4];
var result = arr.some(function (item, index) {
  if (item < 3) {
    return true
  }
})
console.log(result);  // true
复制代码
  • join(根据条件对数组组合成字符串)
var arr = [1, 2, 3, 4];
var result = arr.join(',');
console.log(result);
复制代码
  • reverse(将数组反转)
var arr = [1, 2, 3, 4];
var result = arr.reverse();
console.log(result);
复制代码

常用的对象api

  • for in
  • hasOwnProperty(检查属性是不是对象自有的,排除从原型链找到的属性)
 var obj = {
  x: 10,
  y: 20,
  z: 30
}

for (var key in obj) {
  if (obj.hasOwnProperty(key)) {
    console.log(key + ':' + obj[key]);
  }
}
复制代码

问题:

获取当前日期

function formatDate(dt) {
  if (!dt) {
    dt = new Date();
  }
  var year = dt.getFullYear();
  var month = dt.getMonth() + 1;
  var date = dt.getDate();

  if (month < 10) {
    month = '0' + month;
  }

  if (date < 10) {
    date = '0' + date;
  }

  return year + '-' + month + '-' + date;
}

var nowDate = new Date();
var formatDate = formatDate(nowDate);
console.log(formatDate);
复制代码

获取随机数,要求长度一致的字符串格式

function randomStr(len) {
  var random = Math.random();
  random = random + '0000000000'; // 防止自动生成的数字不满足长度报错并且强制转换成字符串
  return random.substr(0, len)
}

console.log(randomStr(20));
复制代码

写一个能遍历对象和数组的通用forEach函数

function forEach(obj, fn) {
  if (obj instanceof Array) {
    obj.forEach(function (item, index) {
      fn(index, item);
    })
  } else {
    for (var key in obj) {
      if (obj.hasOwnProperty(key)) {
        fn(key, obj[key]);
      }
    }
  }
}

var arr = [1, 2, 3, 4];
forEach(arr, function (index, item) {
  console.log(index + ',' + item);
});

var obj = {
  x: 10,
  y: 20
};
forEach(obj, function (index, item) {
  console.log(index + ',' + item);
});
复制代码

后续还在持续更新中



原文发布时间为:2018年06月26日
原文作者:石燕平
本文来源: 掘金  如需转载请联系原作者
相关文章
|
13天前
|
前端开发 JavaScript 网络协议
前端最常见的JS面试题大全
【4月更文挑战第3天】前端最常见的JS面试题大全
33 5
N..
|
25天前
|
存储 JavaScript 前端开发
JavaScript基础知识
JavaScript基础知识
N..
16 1
|
3天前
|
JavaScript 前端开发 测试技术
「一劳永逸」送你21道高频JavaScript手写面试题(上)
「一劳永逸」送你21道高频JavaScript手写面试题
20 0
|
1月前
|
设计模式 JavaScript 前端开发
最常见的26个JavaScript面试题和答案
最常见的26个JavaScript面试题和答案
42 1
|
1月前
|
存储 JavaScript 前端开发
【JavaScript】面试手撕浅拷贝
引入 浅拷贝和深拷贝应该是面试时非常常见的问题了,为了能将这两者说清楚,于是打算用两篇文章分别解释下深浅拷贝。 PS: 我第一次听到拷贝这个词,有种莫名的熟悉感,感觉跟某个英文很相似,后来发现确实Copy的音译,感觉这翻译还是蛮有意思的
45 6
|
1月前
|
JavaScript 前端开发
【JavaScript】面试手撕节流
上篇我们讲了防抖,这篇我们就谈谈防抖的好兄弟 -- 节流。这里在老生常谈般的提一下他们两者之间的区别,顺带给读者巩固下。
51 3
|
2月前
|
前端开发 JavaScript UED
【JavaScript】面试手撕防抖
防抖: 首先它是常见的性能优化技术,主要用于处理频繁触发的浏览器事件,如窗口大小变化、滚动事件、输入框内容改变等。在用户连续快速地触发同一事件时,防抖机制会确保相关回调函数在一个时间间隔内只会被执行一次。
36 0
|
2月前
|
前端开发 JavaScript 算法
【JavaScript】面试手撕数组排序
这章主要讲的是数组的排序篇,我们知道面试的时候,数组的排序是经常出现的题目。所以这块还是有必要进行一下讲解的。笔者观察了下前端这块的常用算法排序题,大概可以分为如下
24 2
|
2月前
|
JavaScript 前端开发 索引
【JavaScript】面试手撕数组原型链(易)
续借上文,这篇文章主要讲的是数组原型链相关的考题,有些人可能会纳闷,数组和原型链之间有什么关系呢?我们日常使用的数组forEach,map等都是建立在原型链之上的。举个🌰,如我有一个数组const arr = [1,2,3]我想要调用arr.sum方法对arr数组的值进行求和,该如何做呢?我们知道数组没有sum函数,于是我们需要在数组的原型上定义这个函数,才能方便我们调用,具体代码如下。接下来我们就是采用这种方式去实现一些数组常用的方法。
39 6
|
2月前
|
JavaScript 前端开发
【JavaScript】面试手写题精讲之数组(上)
该专题主要是讲解我们在面试的时候碰到一些JS的手写题, 确实这种手写题还是比较恶心的。有些时候好不容易把题目写出来了,突然面试官冷不丁来一句有没有更优的解法,直接让我们僵在原地。为了解决兄弟们的这些困扰,这个专题于是就诞生啦。我们会将一些常见的不是最优解的答案作为对比,方便大家更好理解。
37 3