前端js面试题(高级)

前端js面试题(高级)

1、ES6模块化如何使用?开发环境如何打包?

export语法&&import语法
开发环境可用webpack ,rollup.js 模块打包工具

2、Class和普通构造函数有何区别

1、class在语法上更贴近面向对象的写法。
2、class实现继承更加易读易理解。
3、本质还是语法糖,使用prototype
一、构造函数

function MathHandle(x,y){
    this.x = x
    this.y = y
}

MathHandle.prototype.add = function(){
    return this.x +  this.y
}

var m = new MathHandle(1,2)
console.log(m.add())

二、class基本语法

class MathHandle{
    constructor(x,y){
        this.x = x
        this.y = y
    }
    add(){
        return this.x + this.y
    }
}

const m = new MathHandle(1,2)
console.log(m.add())

三、语法糖
在上述两段代码中分别加入如下代码,运行。

console.log(typeof MathHandle) // 'function'
console.log(MathHandle.prototype.constructor === MathHandle) //true
console.log(m.__proto__ === MathHandle.prototype) //true

运行结果一致。我认为,class是构造函数的语法糖。
四、 继承
1、构造函数形式的继承

//动物
function Animal(){
    this.eat = function (){
        console.log('Animal eat')
    }
}

//狗
function Dog() {
    this.bark = function (){
        console.log('Dog bark')
    }
}

Dog.prototype = new Animal()

var hashiqi = new Dog()
hashiqi.bark()
hashiqi.eat()

2、class继承

class Animal {
    constructor(name){
        this.name = name
    }
    eat(){
        alert(this.name + ' eat')
    }
}

class Dog extends Animal {
    constructor(name){
        super(name) //super就是被继承的对象的constructer
    }
    say(){
        alert(this.name + ' say')
    }
}

const dog = new Dog('哈士奇')
dog.say()
dog.eat()

4、总结一下ES6其他常用功能

1.let && const
let命令也用于声明对象,但是作用域为局部。

{
    let a = 10;
    var b = 1;
}

在函数外部可以获取到b,获取不到a,因此例如for循环计数器就适合使用let。

const用于声明一个常量,设定后值不会再改变。

const PI = 3.1415;
PI // 3.1415
PI = 3;

强行对其进行重新赋值会报错。
2、iterable类型
为了统一集合类型,ES6标准引入了新的iterable类型,Array、Map和Set都属于iterable类型,具有iterable类型的集合可以通过新的for … of循环来遍历。

var a = ['A', 'B', 'C'];
var s = new Set(['A', 'B', 'C']);
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
for (var x of a) { // 遍历Array
    alert(x);
}
for (var x of s) { // 遍历Set
    alert(x);
}
for (var x of m) { // 遍历Map
    alert(x[0] + '=' + x[1]);
}

Map相关操作方法如下,Set同理:

var m = new Map(); // 空Map
m.set('Adam', 67); // 添加新的key-value
m.set('Bob', 59);
m.has('Adam'); // 是否存在key 'Adam': true
m.get('Adam'); // 67
m.delete('Adam'); // 删除key 'Adam'
m.get('Adam'); // undefined

3、解构赋值
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。
例如数组:

let [a, b, c] = [1, 2, 3];
//等同于
let a = 1;
let b = 2;
let c = 3;

对象的解构赋值:获取对象的多个属性并且使用一条语句将它们赋给多个变量。

var {
  StyleSheet,
  Text,
  View
} = React;

等同于

var StyleSheet = React.StyleSheet
...

4.箭头函数
ES6中新增箭头操作符用于简化函数的写法,操作符左边为参数,右边为具体操作和返回值。

var sum = (num1, num2) => { return num1 + num2; }
//等同于
var sum = function(num1, num2) {
    return num1 + num2;
 }

箭头函数还修复了this的指向,使其永远指向词法作用域:

var obj = {
    birth: 1990,
    getAge: function () {
        var b = this.birth; // 1990
        var fn = () => new Date().getFullYear() - this.birth; // this指向obj对象
        return fn();
    }
};
obj.getAge(); // 25

5.延展操作符
通过它可以将数组作为参数直接传入函数:

var people=['Wayou','John','Sherlock'];
function sayHello(people1,people2,people3){
    console.log(`Hello ${people1},${people2},${people3}`);
}
//改写为
sayHello(...people);//输出:Hello Wayou,John,Sherlock 

在函数定义时可以通过…rest获取定义参数外的所有参数:

unction foo(a, b, ...rest) {
    console.log('a = ' + a);
    console.log('b = ' + b);
    console.log(rest);
}

foo(1, 2, 3, 4, 5);
// 结果:
// a = 1
// b = 2
// Array [ 3, 4, 5 ]

6.类
ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类,与多数传统语言类似。

//定义类
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}

5、原型如何实际应用

JS中的原型
原型机制(prototype)是JavaScript中非常重要的机制,通过[[prototype]],我们可以轻易地实现构造函数与其实例的继承与扩展。

  • 定义构造函数
  • 定义生成实例接口
  • 定义初始化函数
  • 提供扩展接口(插件机制)
  • 提供对外接口
  • 绑定原型

命名为Sojourn.js

function (window) {
  // 定义属于自己的对象
  var Sojourn = {}

  // 定义构造函数
  function S(dom, selector) {
    var i, len = dom ? dom.length : 0;
    for (i = 0; i < len; i++) {
      this[i] = dom[i];
    }
    this.length = len;
    this.selector = selector || '';
  }

  // 定义生成实例接口
  Sojourn.S = function (dom, selector) {
    return new S(dom, selector);
  }

  // 定义初始化函数
  Sojourn.init = function (selector) {
    var slice = Array.prototype.slice;
    var dom = slice.call(document.querySelectorAll(selector));
    return Sojourn.S(dom, selector);
  }

  // 提供对外接口
  var $ = Sojourn.init;

  // 提供扩展接口
  $.fn = {
    constructor: Sojourn.S,
    // 添加方法

    // 定义一个修改元素html内容的方法
    html: function (content) {
      console.log(this);
      if (content) {
        this[0].innerHTML = content;
      } else {
        alert('no change');
      }
      // 返回dom对象以实现链式调用
      return this;
    }
  }

  // 绑定原型
  Sojourn.S.prototype = S.prototype = $.fn;

  // 绑定到全局对象
  window.$ = $;
})(window)

在HTML中使用Sojourn.js

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>prototype-test</title>
</head>

<body>
  <div id="div1">prototype test</div>

  <script src="./sojourn.js"></script>
  <script>
    // 一秒钟后使用构造的方法改变dom元素
    setTimeout(function () {
      var div1 = $('#div1');
      // 链式调用
      div1.html().html('use Sojourn.js');

      // 扩展插件
      $.fn.getNodeName = function () {
        alert(this[0].nodeName);
      }

      div1.getNodeName();
    }, 1000);
  </script>
</body>

</html>

6、原型如何满足扩展

提供扩展接口(插件机制)
提供对外接口
我们便可以将一些实用的原型方法当静态方法实用了,ES5还为我们定义了以下7个方法:分别是 every,some,map,forEach,filter,reduce,reduceRight方法,
巧用Object对象中提供的方法 defineProperty(),defineProperty接收三个参数并且都为必填信息
第一个参数:目标对象
第二个参数:需要定义的属性或方法的名字
第三个参数:目标属性所拥有的特性
前面两个参数较为简单我们完全可以略过,主要说一下第三个参数。
alue:属性的值(不用多说了)
writable:如果为false,属性的值就不能被重写,只能为只读了
configurable:总开关,一旦为false,就不能再设置他的(value,writable,configurable)
enumerable:是否能在for…in循环中遍历出来或在Object.keys中列举出来。

7、什么是单线程?和异步有何关系?

https://blog.csdn.net/weixin_39141802/article/details/79466917

8、什么是event-loop?

http://www.ruanyifeng.com/blog/2013/10/event_loop.html

9、目前解决JS异步的方案有哪些?

callback 容易掉入回调地狱
Promise
promise有三种状态:等待中 pending;已完成 fulfilled;已拒绝 reject;
Generator
我们希望以同步方式写异步代码,可以使逻辑清晰,代码简洁,为了实现这种目的,我们又演进出generator方案,

function * add(x){
   yield  x + 50;
   yield x + 100;
   return x + 150;
}
let  test = add(5);
test.next(); //done: true , value: 55
test.next(); //done: true , value: 105
test.next(); //done: true , value: 155
  • 定义Generator时,需要使用function*。
  • 使用时生成一个Generator对象。
  • 执行.next()激活暂停状态,开始执行内部代码,直到遇到yield,返回此时执行的结果,并记住此时执行的上下文,暂停。
  • 再次执行.next()时重复第三步。

asnyc/await
ES7的asnyc/await号称是异步的终极解决方案,让我们以同步的方式来书写异步代码,这样看起来更简洁,逻辑更清晰。
async与genertor的写法类似,具备更好的语义,并且返回的是promise

  • async 表示这是一个async函数,而await只能在这个函数里面使用。
  • await 表示在这里等待await后面的操作执行完毕,再执行下一句代码。
  • await 后面紧跟着的最好是一个耗时的操作或者是一个异步操作。
  • await后面必须是一个Promise对象,如果不是会被转化为一个已完成状态的Promise
async function getResult() {
	try {
		res = await ajax('http://url1', data);
		res = await ajax('http://url2', data);
		res = await ajax('http://url3', data);
		res = await ajax('http://url4', data);
		return res;
	} catch (err) {
		return handleErroe(err)
	}
}

10、如果只用jquery如何解决异步

使用 jQuery.getScript

11、Promise的标准

https://www.jianshu.com/p/4d266538f364

12、async/await的使用

ES7的asnyc/await号称是异步的终极解决方案,让我们以同步的方式来书写异步代码,这样看起来更简洁,逻辑更清晰。
async与genertor的写法类似,具备更好的语义,并且返回的是promise

  • async 表示这是一个async函数,而await只能在这个函数里面使用。
  • await 表示在这里等待await后面的操作执行完毕,再执行下一句代码。
  • await 后面紧跟着的最好是一个耗时的操作或者是一个异步操作。
  • await后面必须是一个Promise对象,如果不是会被转化为一个已完成状态的Promise
async function getResult() {
	try {
		res = await ajax('http://url1', data);
		res = await ajax('http://url2', data);
		res = await ajax('http://url3', data);
		res = await ajax('http://url4', data);
		return res;
	} catch (err) {
		return handleErroe(err)
	}
}

13、什么是vdom,为何要用vdom

https://blog.csdn.net/yczz/article/details/51516526

14、vdom如何使用,核心函数有哪些?

https://blog.csdn.net/yczz/article/details/51516526

15、diff算法

https://blog.csdn.net/one_girl/article/details/81086289

16、之前使用jquery和现在使用vue和React框架的区别

三大框架与jQuery的对比
  尽管三大框架目前都是非常流行的,但是不得不说,jQuery的使用还是大多数(90%),但是选择三大框架还是选择jQuery?

如果你要做单页面应用,那么你就选择三大框架; 如果你要做多页应用,你就选择jQuery。
如果你的数据都是在在服务器端进行修改的,那么毫无疑问,使用三大框架你也没法管理数据,所以使用jQuery;
但是,如果你的数据都是在客户端的,即前端需要处理大量的数据,那么这时就需要选用三大框架了,比如vue的store仓库、比如react的store,他们对于数据的存储都有很好的管理能力。
单项数据流更使得应用便于管理,如react的store -> view -> action -> store -> view ->
action。。。 如此循环往复的单项数据流。
如果你要频繁的手动操作DOM,那么选择jQuery,毕竟jQuery封装了大量的兼容性的DOM操作api;
而如果你的项目是数据驱动的,那么选择vue、react,因为你只要给定数据,就可以使得页面得到渲染了,
而不需要操作dom,或者说,有了react,dom操作就不存在了。

17、如何理解MVVM

https://www.cnblogs.com/goloving/p/8520030.html

18、vue如何实现响应式

https://cn.vuejs.org/v2/guide/reactivity.html 官网
https://www.cnblogs.com/alsy/p/7801029.html

19、vue如何解析模板

https://cn.vuejs.org/v2/guide/syntax.html

20、介绍vue的实现流程

21、对组件化的理解

https://www.jianshu.com/p/b3427e53e57f

22、JSX是什么

https://www.infoq.cn/article/react-jsx-and-component
https://www.cnblogs.com/zourong/p/6043914.html

23、JSX和vdom什么关系

为何需要 vdom : JSX 需要渲染成 html,还有 rerender
React.createElement 和 h ,都生成 vnode
何时 patch: React.render(…) 和 setState
自定义组件的解析:初始化实例,然后执行 render

24、简述React的setState

https://www.cnblogs.com/isLiu/p/8313063.html

25、如何比较React和vue

https://www.jianshu.com/p/b7cd52868e95?from=groupmessage

26、hybrid是什么,为何要使用hybird 27、hybirid如何更新上线 28、hybird和h5有何区别

https://www.e-learn.cn/content/javascript/422462

29、JS如何与客户端通信

https://blog.csdn.net/zhanghongrui1988/article/details/77340267

发布了9 篇原创文章 · 获赞 24 · 访问量 9274
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览