前端面试javascript要点简述(上)

基础部分

1.JS中使用typeof能得到哪些类型?(JS变量类型)

  • 空类型 null(=>object) undefined
  • 值类型 number string boolean
  • 引用类型 (对象、数组)object function

1.1 JS内置函数

  • Number, String, Boolean, Object, Array, Function, RegExp, Date, Error
  • 内置对象Math, JSON

2.使用=====的区别(类型强转)

  • ==用于弱比较,如下面都成立 100=='100', 0 == nullnull==undefined
  • ===用于严格比较,上述例子都不成立,返回false
  • 实际开发中,除了要判断nullundefined外,其他比较建议都使用3等号===(Jquery源码的建议)

3. instanceof是如何执行的(原型与原型链)

  • obj.__proto__ === Object.prototype (__proto__指向其构造函数的prototype),
  • 每个对象都有__proto__ ,每个函数都有 prototype
  • arr instanceof Arrayarr.__proto__ 隐式原型查找是否等于Array的显示原型 Array.prototype
  • Object instanceof FunctionFunction instanceof Object // true

3.1 写一个继承例子

  • 对象可通过原型链进行继承
    来自原型对象的所有属性被所有实例共享
    如果要新增原型属性和方法,则必须放在 childComponent.prototype = new parentComponent(); 这样的语句之后执行
// 父级函数
function parentComponent(name) {
    this.name = name;
    this.alert = function() {
        alert('parentComponent alert');
    }
}
// 父级方法
parentComponent.prototype.prototypeAlert = function() {
    alert('parentComponent.prototype.prototypeAlert')
}
// 子级函数
function childComponent() {
    
}
// 继承
childComponent.prototype = new parentComponent();
// 实例化 并调用父级方法
var c = new childComponent();
c.alert();
c.prototypeAlert();
  • 通过call进行继承
    只能继承父类的实例属性和方法,不能继承原型属性/方法
    无法实现函数复用,每个子类都有父类实例函数的副本,影响性能
// 父级函数
function parentComponent(name) {
    this.name = name;
    this.alert = function() {
        alert('parentComponent alert');
    }
}
// 子级函数
function childComponent(name) {
    // 继承
    parentComponent.call(this, name)
}
// 实例化 并调用父级方法
var c = new childComponent();
c.alert();

4.实现数组的随机排序(基础算法)

4.1 数字类型数组小到大排序

let numbers = [4, 2, 5, 1, 3]; 
numbers.sort((a, b) => a - b); 
console.log(numbers);

4.2 数组随机排序

不太严谨的写法

let strArr = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'];
strArr.sort((a, b) => Math.random() - 0.5); 
console.log(strArr);

相对严谨的写法1

let strArr = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'];
let strObjArr = [];
strArr.forEach((str, index) => {
    strObjArr.push({str, index, r: Math.random()})
})
strObjArr.sort((a, b) => a.r-b.r); 
console.log(strObjArr);

相对严谨的写法2(推荐)

let strArr = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'];
shuffle(strArr);
function shuffle(arr) {
  var i = arr.length, t, j;
  while (i) {
    j = Math.floor(Math.random() * i--);
    t = arr[i];
    arr[i] = arr[j];
    arr[j] = t;
  }
}
// es6
function shuffleES6(arr) {
	var i = arr.length;
	while(i) {
		j = Math.floor(Math.random() * i--);
		[arr[j], arr[i]] = [arr[i], arr[j]];
	}
}

4.3 数组去重

// es5
let strArr = ['a', 'b', 'c', 'd', '1', 'f', 'g', 'a', 'b', 'c', '1'];
let result = strArr.filter((item, index, arr) => arr.indexOf(item) === index);
console.log(result);
// es6
let strArr = ['a', 'b', 'c', 'd', '1', 'f', 'g', 'a', 'b', 'c', '1'];
let result = [...new Set(strArr)];
console.log(result);

5.apply、bind、call

  • 三者都可以通过第一个参数来改变this的引用
  • apply第二个参数是一个数组 func.apply(thisArg, [argsArray]),而callbind第二之后的参数同样是对应的函数参数列表function.bind(thisArg[, arg1[, arg2[, ...]]])function.call(thisArg, arg1, arg2, ...)
  • bind返回值是一个绑定函数
  • 从性能方面,相比之下call较优,因此用得较多

6.闭包

闭包也可以理解为背包。自由变量的值是根据函数声明定义时的上下文,而不是函数执行时的上下文

使用场景

  • 函数作为返回值
  • 函数作为参数进行传递

参考代码

  • 函数作为返回值
function func() {
    var a = 100;    
    return function() {        
        console.log(++a);
    }
}
var a = 200;
var fn = func();
fn(); // 101
  • 函数作为参数进行传递
function func() {
    var a = 100;    
    return function() {        
        return ++a;
    }
}
function run(fn) {
    var a = 200;
    var res = fn();
    console.log(res());
}
run(func); // 101
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值