北京上云网站建设公司,成都注册公司需要什么材料和手续,浙江省建设网站首页,网站建设公司 盐城市原型
JavaScript中的对象都有一个特殊的 prototype 内置属性#xff0c;其实就是对其他对象的引用
几乎所有的对象在创建时 prototype 属性都会被赋予一个非空的值#xff0c;我们可以把这个属性当作一个备用的仓库
当试图引用对象的属性时会出发get操作#xff0c;第一步时…原型
JavaScript中的对象都有一个特殊的 prototype 内置属性其实就是对其他对象的引用
几乎所有的对象在创建时 prototype 属性都会被赋予一个非空的值我们可以把这个属性当作一个备用的仓库
当试图引用对象的属性时会出发get操作第一步时检查对象本身是否有这个属性如果有就使用它没有就去原型中查找。一层层向上直到Object.prototype顶层基于原型扩展描述一下原型链什么是原型链原型的继承ES5和ES6继承与不同点。 HTTP状态码
1xx 信息性状态码 websocket upgrade2xx 成功状态码 200 服务器已成功处理了请求204(没有响应体)206(范围请求 暂停继续下载) 3xx 重定向状态码 301(永久) 请求的页面已永久跳转到新的url302(临时) 允许各种各样的重定向一般情况下都会实现为到 GET 的重定向但是不能确保 POST 会重定向为 POST303 只允许任意请求到 GET 的重定向304 未修改自从上次请求后请求的网页未修改过307307 和 302 一样除了不允许 POST 到 GET 的重定向 4xx 客户端错误状态码 400 客户端参数错误401 没有登录403 登录了没权限 比如管理系统404 页面不存在405 禁用请求中指定的方法 5xx 服务端错误状态码 500 服务器错误服务器内部错误无法完成请求502 错误网关服务器作为网关或代理出现错误503 服务不可用服务器目前无法使用504 网关超时网关或代理服务器未及时获取请求
如何优化关键渲染路径
为尽快完成首次渲染我们需要最大限度减小以下三种可变因素
1关键资源的数量。
2关键路径长度。
3关键字节的数量。
关键资源是可能阻止网页首次渲染的资源。这些资源越少浏览器的工作量就越小对 CPU 以及其他资源的占用也就越少。同样关键路径长度受所有关键资源与其字节大小之间依赖关系图的影响某些资源只能在上一资源处理完毕之后才能开始下载并且资源越大下载所需的往返次数就越多。最后浏览器需要下载的关键字节越少处理内容并让其出现在屏幕上的速度就越快。要减少字节数我们可以减少资源数将它们删除或设为非关键资源此外还要压缩和优化各项资源确保最大限度减小传送大小。
优化关键渲染路径的常规步骤如下
1对关键路径进行分析和特性描述资源数、字节数、长度。
2最大限度减少关键资源的数量删除它们延迟它们的下载将它们标记为异步等。
3优化关键字节数以缩短下载时间往返次数。
4优化其余关键资源的加载顺序您需要尽早下载所有关键资产以缩短关键路径长度
代码输出结果
Promise.resolve(1).then(2).then(Promise.resolve(3)).then(console.log)
输出结果如下
1
看到这个题目好多的then实际上只需要记住一个原则.then 或.catch 的参数期望是函数传入非函数则会发生值透传。
第一个then和第二个then中传入的都不是函数一个是数字一个是对象因此发生了透传将resolve(1) 的值直接传到最后一个then里直接打印出1。
常见的浏览器内核比较
Trident 这种浏览器内核是 IE 浏览器用的内核因为在早期 IE 占有大量的市场份额所以这种内核比较流行以前有很多网页也是根据这个内核的标准来编写的但是实际上这个内核对真正的网页标准支持不是很好。但是由于 IE 的高市场占有率微软也很长时间没有更新 Trident 内核就导致了 Trident 内核和 W3C 标准脱节。还有就是 Trident 内核的大量 Bug 等安全问题没有得到解决加上一些专家学者公开自己认为 IE 浏览器不安全的观点使很多用户开始转向其他浏览器。Gecko 这是 Firefox 和 Flock 所采用的内核这个内核的优点就是功能强大、丰富可以支持很多复杂网页效果和浏览器扩展接口但是代价是也显而易见就是要消耗很多的资源比如内存。Presto Opera 曾经采用的就是 Presto 内核Presto 内核被称为公认的浏览网页速度最快的内核这得益于它在开发时的天生优势在处理 JS 脚本等脚本语言时会比其他的内核快3倍左右缺点就是为了达到很快的速度而丢掉了一部分网页兼容性。Webkit Webkit 是 Safari 采用的内核它的优点就是网页浏览速度较快虽然不及 Presto 但是也胜于 Gecko 和 Trident缺点是对于网页代码的容错性不高也就是说对网页代码的兼容性较低会使一些编写不标准的网页无法正确显示。WebKit 前身是 KDE 小组的 KHTML 引擎可以说 WebKit 是 KHTML 的一个开源的分支。Blink 谷歌在 Chromium Blog 上发表博客称将与苹果的开源浏览器核心 Webkit 分道扬镳在 Chromium 项目中研发 Blink 渲染引擎即浏览器核心内置于 Chrome 浏览器之中。其实 Blink 引擎就是 Webkit 的一个分支就像 webkit 是KHTML 的分支一样。Blink 引擎现在是谷歌公司与 Opera Software 共同研发上面提到过的Opera 弃用了自己的 Presto 内核加入 Google 阵营跟随谷歌一起研发 Blink。
代码输出结果
var a, b
(function () {console.log(a);console.log(b);var a (b 3);console.log(a);console.log(b);
})()
console.log(a);
console.log(b);
输出结果
undefined
undefined
3
3
undefined
3
这个题目和上面题目考察的知识点类似b赋值为3b此时是一个全局变量而将3赋值给aa是一个局部变量所以最后打印的时候a仍旧是undefined。
参考 前端进阶面试题详细解答
代码输出结果
function foo(something){this.a something
}var obj1 {foo: foo
}var obj2 {}obj1.foo(2);
console.log(obj1.a); // 2obj1.foo.call(obj2, 3);
console.log(obj2.a); // 3var bar new obj1.foo(4)
console.log(obj1.a); // 2
console.log(bar.a); // 4
输出结果 2 3 2 4
解析
首先执行obj1.foo(2); 会在obj中添加a属性其值为2。之后执行obj1.aa是右obj1调用的所以this指向obj打印出2执行 obj1.foo.call(obj2, 3) 时会将foo的this指向obj2后面就和上面一样了所以会打印出3obj1.a会打印出2最后就是考察this绑定的优先级了new 绑定是比隐式绑定优先级高所以会输出4。
Promise.resolve
Promise.resolve function(value) {// 1.如果 value 参数是一个 Promise 对象则原封不动返回该对象if(value instanceof Promise) return value;// 2.如果 value 参数是一个具有 then 方法的对象则将这个对象转为 Promise 对象并立即执行它的then方法if(typeof value object then in value) {return new Promise((resolve, reject) {value.then(resolve, reject);});}// 3.否则返回一个新的 Promise 对象状态为 fulfilledreturn new Promise(resolve resolve(value));
}
实现模板字符串解析功能
题目描述:
let template 我是{{name}}年龄{{age}}性别{{sex}};
let data {name: 姓名,age: 18
}
render(template, data); // 我是姓名年龄18性别undefined
实现代码如下:
function render(template, data) {let computed template.replace(/\{\{(\w)\}\}/g, function (match, key) {return data[key];});return computed;
}
Nginx的概念及其工作原理
Nginx 是一款轻量级的 Web 服务器也可以用于反向代理、负载平衡和 HTTP 缓存等。Nginx 使用异步事件驱动的方法来处理请求是一款面向性能设计的 HTTP 服务器。
传统的 Web 服务器如 Apache 是 process-based 模型的而 Nginx 是基于event-driven模型的。正是这个主要的区别带给了 Nginx 在性能上的优势。
Nginx 架构的最顶层是一个 master process这个 master process 用于产生其他的 worker process这一点和Apache 非常像但是 Nginx 的 worker process 可以同时处理大量的HTTP请求而每个 Apache process 只能处理一个。
介绍下 promise 的特性、优缺点内部是如何实现的动手实现 Promise
1Promise基本特性
1、Promise有三种状态pending(进行中)、fulfilled(已成功)、rejected(已失败)2、Promise对象接受一个回调函数作为参数, 该回调函数接受两个参数分别是成功时的回调resolve和失败时的回调reject另外resolve的参数除了正常值以外 还可能是一个Promise对象的实例reject的参数通常是一个Error对象的实例。3、then方法返回一个新的Promise实例并接收两个参数onResolved(fulfilled状态的回调)onRejected(rejected状态的回调该参数可选)4、catch方法返回一个新的Promise实例5、finally方法不管Promise状态如何都会执行该方法的回调函数不接受任何参数6、Promise.all()方法将多个多个Promise实例包装成一个新的Promise实例该方法接受一个由Promise对象组成的数组作为参数(Promise.all()方法的参数可以不是数组但必须具有Iterator接口且返回的每个成员都是Promise实例)注意参数中只要有一个实例触发catch方法都会触发Promise.all()方法返回的新的实例的catch方法如果参数中的某个实例本身调用了catch方法将不会触发Promise.all()方法返回的新实例的catch方法7、Promise.race()方法的参数与Promise.all方法一样参数中的实例只要有一个率先改变状态就会将该实例的状态传给Promise.race()方法并将返回值作为Promise.race()方法产生的Promise实例的返回值8、Promise.resolve()将现有对象转为Promise对象如果该方法的参数为一个Promise对象Promise.resolve()将不做任何处理如果参数thenable对象(即具有then方法)Promise.resolve()将该对象转为Promise对象并立即执行then方法如果参数是一个原始值或者是一个不具有then方法的对象则Promise.resolve方法返回一个新的Promise对象状态为fulfilled其参数将会作为then方法中onResolved回调函数的参数如果Promise.resolve方法不带参数会直接返回一个fulfilled状态的 Promise 对象。需要注意的是立即resolve()的 Promise 对象是在本轮“事件循环”event loop的结束时执行而不是在下一轮“事件循环”的开始时。9、Promise.reject()同样返回一个新的Promise对象状态为rejected无论传入任何参数都将作为reject()的参数
2Promise优点
①统一异步 API Promise 的一个重要优点是它将逐渐被用作浏览器的异步 API 统一现在各种各样的 API 以及不兼容的模式和手法。 ②Promise 与事件对比 和事件相比较 Promise 更适合处理一次性的结果。在结果计算出来之前或之后注册回调函数都是可以的都可以拿到正确的值。 Promise 的这个优点很自然。但是不能使用 Promise 处理多次触发的事件。链式处理是 Promise 的又一优点但是事件却不能这样链式处理。 ③Promise 与回调对比 解决了回调地狱的问题将异步操作以同步操作的流程表达出来。 ④Promise 带来的额外好处是包含了更好的错误处理方式包含了异常处理并且写起来很轻松因为可以重用一些同步的工具比如 Array.prototype.map() 。
3Promise缺点
1、无法取消Promise一旦新建它就会立即执行无法中途取消。2、如果不设置回调函数Promise内部抛出的错误不会反应到外部。3、当处于Pending状态时无法得知目前进展到哪一个阶段刚刚开始还是即将完成。4、Promise 真正执行回调的时候定义 Promise 那部分实际上已经走完了所以 Promise 的报错堆栈上下文不太友好。
4简单代码实现 最简单的Promise实现有7个主要属性, state(状态), value(成功返回值), reason(错误信息), resolve方法, reject方法, then方法
class Promise{constructor(executor) {this.state pending;this.value undefined;this.reason undefined;let resolve value {if (this.state pending) {this.state fulfilled;this.value value;}};let reject reason {if (this.state pending) {this.state rejected;this.reason reason;}};try {// 立即执行函数executor(resolve, reject);} catch (err) {reject(err);}}then(onFulfilled, onRejected) {if (this.state fulfilled) {let x onFulfilled(this.value);};if (this.state rejected) {let x onRejected(this.reason);};}
}5面试够用版
function myPromise(constructor){ let selfthis;self.statuspending //定义状态改变前的初始状态 self.valueundefined;//定义状态为resolved的时候的状态 self.reasonundefined;//定义状态为rejected的时候的状态 function resolve(value){//两个pending保证了了状态的改变是不不可逆的 if(self.statuspending){self.valuevalue;self.statusresolved; }}function reject(reason){//两个pending保证了了状态的改变是不不可逆的if(self.statuspending){self.reasonreason;self.statusrejected; }}//捕获构造异常 try{constructor(resolve,reject);}catch(e){reject(e);}
}
myPromise.prototype.thenfunction(onFullfilled,onRejected){ let selfthis;switch(self.status){case resolved: onFullfilled(self.value); break;case rejected: onRejected(self.reason); break;default: }
}// 测试
var pnew myPromise(function(resolve,reject){resolve(1)});
p.then(function(x){console.log(x)})
//输出16大厂专供版
const PENDING pending;
const FULFILLED fulfilled;
const REJECTED rejected;
const resolvePromise (promise, x, resolve, reject) {if (x promise) {// If promise and x refer to the same object, reject promise with a TypeError as the reason.reject(new TypeError(循环引用))}// if x is an object or function,if (x ! null typeof x object || typeof x function) {// If both resolvePromise and rejectPromise are called, or multiple calls to the same argument are made, the first call takes precedence, and any further calls are ignored.let calledtry { // If retrieving the property x.then results in a thrown exception e, reject promise with e as the reason.let then x.then // Let then be x.then// If then is a function, call it with x as thisif (typeof then function) {// If/when resolvePromise is called with a value y, run [[Resolve]](promise, y)// If/when rejectPromise is called with a reason r, reject promise with r.then.call(x, y {if (called) returncalled trueresolvePromise(promise, y, resolve, reject)}, r {if (called) returncalled truereject(r)})} else {// If then is not a function, fulfill promise with x.resolve(x)}} catch (e) {if (called) returncalled truereject(e)}} else {// If x is not an object or function, fulfill promise with xresolve(x)}
}
function Promise(excutor) {let that this; // 缓存当前promise实例例对象that.status PENDING; // 初始状态that.value undefined; // fulfilled状态时 返回的信息that.reason undefined; // rejected状态时 拒绝的原因 that.onFulfilledCallbacks []; // 存储fulfilled状态对应的onFulfilled函数that.onRejectedCallbacks []; // 存储rejected状态对应的onRejected函数function resolve(value) { // value成功态时接收的终值if(value instanceof Promise) {return value.then(resolve, reject);}// 实践中要确保 onFulfilled 和 onRejected ⽅方法异步执⾏行行且应该在 then ⽅方法被调⽤用的那⼀一轮事件循环之后的新执⾏行行栈中执⾏行行。setTimeout(() {// 调⽤用resolve 回调对应onFulfilled函数if (that.status PENDING) {// 只能由pending状态 fulfilled状态 (避免调⽤用多次resolve reject)that.status FULFILLED;that.value value;that.onFulfilledCallbacks.forEach(cb cb(that.value));}});}function reject(reason) { // reason失败态时接收的拒因setTimeout(() {// 调⽤用reject 回调对应onRejected函数if (that.status PENDING) {// 只能由pending状态 rejected状态 (避免调⽤用多次resolve reject)that.status REJECTED;that.reason reason;that.onRejectedCallbacks.forEach(cb cb(that.reason));}});}// 捕获在excutor执⾏行行器器中抛出的异常// new Promise((resolve, reject) {// throw new Error(error in excutor)// })try {excutor(resolve, reject);} catch (e) {reject(e);}
}
Promise.prototype.then function(onFulfilled, onRejected) {const that this;let newPromise;// 处理理参数默认值 保证参数后续能够继续执⾏行行onFulfilled typeof onFulfilled function ? onFulfilled : value value;onRejected typeof onRejected function ? onRejected : reason {throw reason;};if (that.status FULFILLED) { // 成功态return newPromise new Promise((resolve, reject) {setTimeout(() {try{let x onFulfilled(that.value);resolvePromise(newPromise, x, resolve, reject); //新的promise resolve 上⼀一个onFulfilled的返回值} catch(e) {reject(e); // 捕获前⾯面onFulfilled中抛出的异常then(onFulfilled, onRejected);}});})}if (that.status REJECTED) { // 失败态return newPromise new Promise((resolve, reject) {setTimeout(() {try {let x onRejected(that.reason);resolvePromise(newPromise, x, resolve, reject);} catch(e) {reject(e);}});});}if (that.status PENDING) { // 等待态
// 当异步调⽤用resolve/rejected时 将onFulfilled/onRejected收集暂存到集合中return newPromise new Promise((resolve, reject) {that.onFulfilledCallbacks.push((value) {try {let x onFulfilled(value);resolvePromise(newPromise, x, resolve, reject);} catch(e) {reject(e);}});that.onRejectedCallbacks.push((reason) {try {let x onRejected(reason);resolvePromise(newPromise, x, resolve, reject);} catch(e) {reject(e);}});});}
};map和foreach有什么区别
foreach()方法会针对每一个元素执行提供得函数,该方法没有返回值,是否会改变原数组取决与数组元素的类型是基本类型还是引用类型
map()方法不会改变原数组的值,返回一个新数组,新数组中的值为原数组调用函数处理之后的值
Promise.all
描述所有 promise 的状态都变成 fulfilled就会返回一个状态为 fulfilled 的数组(所有promise 的 value)。只要有一个失败就返回第一个状态为 rejected 的 promise 实例的 reason。
实现
Promise.all function(promises) {return new Promise((resolve, reject) {if(Array.isArray(promises)) {if(promises.length 0) return resolve(promises);let result [];let count 0;promises.forEach((item, index) {Promise.resolve(item).then(value {count;result[index] value;if(count promises.length) resolve(result);}, reason reject(reason));})}else return reject(new TypeError(Argument is not iterable));});
}
说一下购物车的逻辑?
//vue中购物车逻辑的实现
1. 购物车信息用一个数组来存储数组中保存对象对象中有id和count属性2. 在vuex中state中添加一个数据 cartList 用来保存这个数组3. 由于商品详情页需要用到加入购物车功能所以我们需要提供一个mutation, 用来将购物车信息加入 cartList中4. 加入购物车信息的时候遵照如下规则 如果购物车中已经有了该商品信息则数量累加如果没有该商品信息则新增一个对象5. 在商品详情页点击加入购物车按钮的时候调用vuex提供的addToCart这个mutation将当前的商品信息 id count传给addTocart this.$store.commit(addToCart, {id: , count})// js中购物车逻辑的实现
1.商品页点击“加入购物车”按钮触发事件2.事件调用购物车“增加商品”的Js程序函数、对象方法3.向Js程序传递传递“商品id”、“商品数量”等数据4.存储“商品id”、“商品数量”到浏览器的localStorage中**展示购物车中的商品******1.打开购物车页面2.从localStorage中取出“商品Id”、“商品数量”等信息。3.调用服务器端“获得商品详情”的接口得到购物车中的商品信息参数为商品Id4.将获得的商品信息显示在购物车页面。**完成购物车中商品的购买******1.用户对购物车中的商品完成购买流程产生购物订单2.清除localStorage中存储的已经购买的商品信息备注1购物车中商品存储的数据除了“商品id”、“商品数量”之外根据产品要求还可以有其他的信息例如完整的商品详情这样就不用掉服务器接口获得详情了、购物车商品的过期时间超过时间的购物车商品在下次打开网站或者购物车页面时被清除。备注2购物车商品除了存储在localStorage中根据产品的需求不同也可以存储在sessionStorage、cookie、session中或者直接向服务器接口发起请求存储在服务器上。何种情况使用哪种方式存储、有啥区别请自己分析。
进程和线程的区别
进程可以看做独立应用线程不能资源进程是cpu资源分配的最小单位是能拥有资源和独立运行的最小单位线程是cpu调度的最小单位线程是建立在进程的基础上的一次程序运行单位一个进程中可以有多个线程。通信方面线程间可以通过直接共享同一进程中的资源而进程通信需要借助 进程间通信。调度进程切换比线程切换的开销要大。线程是CPU调度的基本单位线程的切换不会引起进程切换但某个进程中的线程切换到另一个进程中的线程时会引起进程切换。系统开销由于创建或撤销进程时系统都要为之分配或回收资源如内存、I/O 等其开销远大于创建或撤销线程时的开销。同理在进行进程切换时涉及当前执行进程 CPU 环境还有各种各样状态的保存及新调度进程状态的设置而线程切换时只需保存和设置少量寄存器内容开销较小。
如何防御 XSS 攻击
可以看到XSS危害如此之大 那么在开发网站时就要做好防御措施具体措施如下
可以从浏览器的执行来进行预防一种是使用纯前端的方式不用服务器端拼接后返回不使用服务端渲染。另一种是对需要插入到 HTML 中的代码做好充分的转义。对于 DOM 型的攻击主要是前端脚本的不可靠而造成的对于数据获取渲染和字符串拼接的时候应该对可能出现的恶意代码情况进行判断。使用 CSP CSP 的本质是建立一个白名单告诉浏览器哪些外部资源可以加载和执行从而防止恶意代码的注入攻击。 CSP 指的是内容安全策略它的本质是建立一个白名单告诉浏览器哪些外部资源可以加载和执行。我们只需要配置规则如何拦截由浏览器自己来实现。通常有两种方式来开启 CSP一种是设置 HTTP 首部中的 Content-Security-Policy一种是设置 meta 标签的方式 对一些敏感信息进行保护比如 cookie 使用 http-only使得脚本无法获取。也可以使用验证码避免脚本伪装成用户执行一些操作。
代码输出结果
Promise.resolve(1).then(2).then(Promise.resolve(3)).then(console.log)
输出结果如下
1
Promise {fulfilled: undefined}
Promise.resolve方法的参数如果是一个原始值或者是一个不具有then方法的对象则Promise.resolve方法返回一个新的Promise对象状态为resolvedPromise.resolve方法的参数会同时传给回调函数。
then方法接受的参数是函数而如果传递的并非是一个函数它实际上会将其解释为then(null)这就会导致前一个Promise的结果会传递下面。
PWA使用过吗serviceWorker的使用原理是啥
渐进式网络应用PWA是谷歌在2015年底提出的概念。基本上算是web应用程序但在外观和感觉上与原生app类似。支持PWA的网站可以提供脱机工作、推送通知和设备硬件访问等功能。
Service Worker是浏览器在后台独立于网页运行的脚本它打开了通向不需要网页或用户交互的功能的大门。 现在它们已包括如推送通知和后台同步等功能。 将来Service Worker将会支持如定期同步或地理围栏等其他功能。 本教程讨论的核心功能是拦截和处理网络请求包括通过程序来管理缓存中的响应。
JavaScript 类数组对象的定义
一个拥有 length 属性和若干索引属性的对象就可以被称为类数组对象类数组对象和数组类似但是不能调用数组的方法。常见的类数组对象有 arguments 和 DOM 方法的返回结果还有一个函数也可以被看作是类数组对象因为它含有 length 属性值代表可接收的参数个数。
常见的类数组转换为数组的方法有这样几种
1通过 call 调用数组的 slice 方法来实现转换
Array.prototype.slice.call(arrayLike);
2通过 call 调用数组的 splice 方法来实现转换
Array.prototype.splice.call(arrayLike, 0);
3通过 apply 调用数组的 concat 方法来实现转换
Array.prototype.concat.apply([], arrayLike);
4通过 Array.from 方法来实现转换
Array.from(arrayLike);
什么是闭包闭包的作用是什么
当一个内部函数被调用就会形成闭包闭包就是能够读取其他函数内部变量的函数。
闭包作用
局部变量无法共享和长久的保存而全局变量可能造成变量污染所以我们希望有一种机制既可以长久的保存变量又不会造成全局污染。