js面试题

  • 如何解决跨域

    • jsonp跨域
    • document.domain + iframe 跨域
    • nodejs中间件代理跨域
    • 后端在头部信息里面设置安全域名
  • 严格模式的限制

    • 变量必须声明后再使用
    • 函数的参数不能有同名属性,否则报错
    • 不能使用 with 语句
  • es6新增

    • 新增模板字符串
    • 箭头函数
    • for-of(用来遍历数据—例如数组中的值。)
    • ES6 将 Promise 对象纳入规范,提供了原生的 Promise 对象。
    • 增加了 let 和 const 命令,用来声明变量。
    • 还有就是引入 module 模块的概念
  • JavaScript 深浅拷贝

    • 浅拷贝
      • Object.assign
      • concat,连接数组,不改变原数组,浅拷贝
    • 深拷贝
      • 可以通过JSON.parse(JSON.stringify(object)) 来解决
  • 什么是 Generator 函数

    • 在Javascript中,一个函数一旦开始执行,就会运行到最后或遇到return时结束,运行期间不会有其它代码能够打断它,也不能从外部再传入值到函数体内

    • 而Generator函数(生成器)的出现使得打破函数的完整运行成为了可能,其语法行为与传统函数完全不同

    • Generator函数是ES6提供的一种异步编程解决方案,形式上也是一个普通函数,但有几个显著的特征:

      • – function关键字与函数名之间有一个星号 “*” (推荐紧挨着function关键字)
      • – 函数体内使用 yield 表达式,定义不同的内部状态 (可以有多个yield)
      • – 直接调用 Generator函数并不会执行,也不会返回运行结果,而是返回一个遍历器对象(Iterator Object)
      • – 依次调用遍历器对象的next方法,遍历 Generator函数内部的每一个状态
{
  // 传统函数
  function foo() {
    return 'hello world'
  }
  foo()   // 'hello world',一旦调用立即执行


  // Generator函数
  function* generator() {
    yield 'status one'         // yield 表达式是暂停执行的标记  
    return 'hello world'
  }
  let iterator = generator()   // 调用 Generator函数,函数并没有执行,返回的是一个Iterator对象
  iterator.next()              // {value: "status one", done: false},value 表示返回值,done 表示遍历还没有结束
  iterator.next()              // {value: "hello world", done: true},value 表示返回值,done 表示遍历结束
}
function *foo(x){
  let y = 2 * (yield (x + 1))
  let z = yield (y / 3)
  return (x+y+z)
}

let it = foo(5)
console.log(it.next()); // { value: 6, done: false }
console.log(it.next(12)); // { value: 8, done: false }
console.log(it.next(13)); // { value: 42, done: true }???
  • 说说负载均衡?
    • 单台服务器共同协作,不让其中某一台或几台超额工作,发挥服务器的最大作用
    • http 重定向负载均衡:调度者根据策略选择服务器以 302 响应请求,缺点只有第一次有效果,后续操作维持在该服务器 dns 负载均衡:解析域名时,访问多个 ip 服务器中的一个(可监控性较弱)原因 - 避免 DOM 渲染的冲突
    • 反向代理负载均衡:访问统一的服务器,由服务器进行调度访问实际的某个服务器,对统一的服务器要求大,性能受到 服务器群的数量

Promise

  • Promise异步读取文件(node核心)
const fs = require('fs');
const path = require('path');

function asyncGetFileByPath(p) {
    return new Promise((resolve, reject) => {
        fs.readFile(path.join(__dirname, p), 'utf-8', (err, data) => {
            if (err) {
                reject(err);
            } else {
                resolve(data);
            }
        })
    })
}
  • 用js实现sleep,用promise
function sleep(time) {
  return new Promise(resolve => setTimeout(resolve, time))
}

const t1 = +new Date()
sleep(3000).then(() => {
  const t2 = +new Date()
  console.log(t2 - t1)
})
  • 实现一个 Scheduler 类,完成对Promise的并发处理,最多同时执行2个任务
class Scheduler {
    constructor() {
        this.tasks = [], // 待运行的任务
        this.usingTask = [] // 正在运行的任务
    }
    // promiseCreator 是一个异步函数,return Promise
    add(promiseCreator) {
        return new Promise((resolve, reject) => {
            promiseCreator.resolve = resolve
            if (this.usingTask.length < 2) {
                this.usingRun(promiseCreator)
            } else {
                this.tasks.push(promiseCreator)
            }
        })
    }

    usingRun(promiseCreator) {
        this.usingTask.push(promiseCreator)
        promiseCreator().then(() => {
            promiseCreator.resolve()
            this.usingMove(promiseCreator)
            if (this.tasks.length > 0) {
                this.usingRun(this.tasks.shift())
            }
        })
    }

    usingMove(promiseCreator) {
        let index = this.usingTask.findIndex(promiseCreator)
        this.usingTask.splice(index, 1)
    }
}

const timeout = (time) => new Promise(resolve => {
    setTimeout(resolve, time)
})

const scheduler = new Scheduler()

const addTask = (time, order) => {
    scheduler.add(() => timeout(time)).then(() => console.log(order))
}

addTask(400, 4) 
addTask(200, 2) 
addTask(300, 3) 
  • js执行顺序的题目,涉及到settimeout、console、process.nextTick、promise.then
console.time('start');

setTimeout(function() {
  console.log(2);
}, 10);

setImmediate(function() {
  console.log(1);
});

new Promise(function(resolve) {
  console.log(3);
  resolve();
  console.log(4);
}).then(function() {
  console.log(5);
  console.timeEnd('start')
});

console.log(6);

process.nextTick(function() {
  console.log(7);
});

console.log(8);

// 3
// 4
// 6
// 8
// 7
// 5
// start: 6.003ms   //计时器
// 1
// 2

宏任务 Macrotask队列真实包含任务:
script(主程序代码),setTimeout, setInterval, setImmediate, I/O, UI rendering

微任务 Microtask队列真实包含任务:
process.nextTick, Promises, Object.observe, MutationObserver

  • call、apply、bind
    • call 经常做继承。

    • apply 经常跟数组有关系,比如借助于数学对象实现数组最大值最小值。

    • bind 不调用函数,但是还想改变this指向,比如改变定时器内部的this指向。

    • bind函数原型

  Function.prototype.bind = function() {
    var args = Array.prototype.slice.call(arguments);
    var context = args.splice(0,1)[0];
    var fn = this;
    var noop = function() {}
    var res =  function() {
        let rest = Array.prototype.slice.call(arguments);
        // this只和运行的时候有关系,所以这里的this和上面的fn不是一码事,new res()和res()在调用的时            候,res中的this是不同的东西
        return fn.apply(this instanceof noop ? this : context, args.concat(rest));
    }
    if(this.prototype) {
        noop.prototype = this.prototype;
    }
    res.prototype = new noop();
    return res;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值