-
如何解决跨域
- 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;
}