闭包 和 作用域
作用域
作用域是指在程序中定义变量的区域,作用域规定了变量与函数的活动范围。
在es6之前,js中只有全局作用域和函数作用域。在这之后,引入了let 和 const ,它们会创建块级作用域。
在函数调用栈中,当内部函数查找一个外部变量,则js引擎就会向上级作用域中查找。这个查找的链条称为作用域链。
闭包
闭包的目的是能在函数的外部作用域中访问函数内部的上下文。通过作用域以及作用域链,我们知道了当前作用域中(outer)的上下文(变量),会在当前调用栈结束调用后被gc销毁。但是通过作用域链,我们可以在一个内部函数(inner)中访问outer作用域中的变量,创建引用关系。这样,就算调用栈执行完毕后也不会销毁outer中被引用的执行上下文。
1 |
|
你是如何组织自己的代码?是使用模块模式,还是使用经典继承的方法?
正常些js方法时使用模块模式,一个IIFE就算是一个模块,互相之间不影响。
继承在react跟node中也是比较常用的。
1 | var jspy = (function() { |
匿名函数的典型用法
匿名函数就是没有名称的函数, 如:
1 | (function () {})() |
宿主对象(host object) 和原生对象(native object)、内置对象的区别
请指出以下代码的区别:function Person(){}、var person = Person()、var person = new Person()?
- 定义了一个名为Person的函数
- 普通的调用Person函数,并将返回值赋值到person变量上。
- 使用new关键字,将Person作为构造函数实例化
call apply bind
1 | Function.prototype.call = function(context) { |
new 实现
1 | function fakeNew() { |
函数防抖和函数节流
防抖函数概念:
该函数只能在指定延时结束后才能调用,如果在过程中重复调用,则重新计时。
应用场景:
- 用户在搜索框输入时的数据查询,指定
n
毫秒 延时,只能在输入完后过了n
毫秒后才会去搜索,中间的持续输入则会重新计时 - 在监听window.onresize事件,并触发某些操作时。
1
2
3
4
5
6
7
8
9
10
11
12
13
function debounce(fn, interval) {
var timer;
return function() {
var _self = this;
if (timer) clearTimeout(timer);
timer = setTimeout(function() {
fn.apply(_self, arguments)
}, interval)
}
}
函数节流:
在规定时间内,函数只能被调用一次。如果单位时间内多次触发,则忽略
应用场景:
- 点击搜索按钮时的防重复。
- 监听scroll事件时
1 | function throttle(fn, interval) { |
什么情况下会使用document.write()
加载需要配合js脚本使用的外部css文件
1
2
3<scirpt>
document.write('<link rel="stylesheet" href="style_neads_js.css">');
</script>在新打开的页面中写入数据时
由于document.write会重写整个页面,异步调用会影响本页面的文档,如果在新窗口空白页调用,就没影响了。新开一个窗口,把本页面取到的数据在新窗口展示。
1 | document.open(); |
特性检测、特性推断、浏览器UA字符串嗅探
Ajax工作原理
跨域方案
图片Ping
图片Ping是客户端向服务器的单向通信,因为src请求资源不属于同源策略,所以一般可以用来做埋点、前端监控,比如监听网页的PV(Page View),UV(Unique Visitor)。
最好是采用1 * 1 像素的透明gif图,因为:
- 能够完成整个 HTTP 请求+响应(尽管不需要响应内容)
- 触发 GET 请求之后不需要获取和处理数据、服务器也不需要发送数据
- 跨域友好
- 执行过程无阻塞
- 相比 XMLHttpRequest 对象发送 GET 请求,性能上更好
- GIF的最低合法体积最小(最小的BMP文件需要74个字节,PNG需要67个字节,而合法的GIF,只需要43个字节)
变量声明提升
js冒泡机制
property(属性)和attribute(特性)
DOM有其默认的基本属性,而这些属性就是所谓的“property”,无论如何,它们都会在初始化的时候再DOM对象上创建。
HTML标签中定义的属性和值会保存该DOM对象的attributes属性里面;
这些attribute属性的JavaScript中的类型是Attr,而不仅仅是保存属性名和值这么简单;
1 | <input id="in_2" sth="whatever"> |
1 | var in2 = document.getElementById('in_2'); |
document load 和 document DOMContentLoaded
- load方法在网页中所有的资源(HTML,CSS,image)都完全加载后才触发
- 当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像和子框架的完成加载
== 和 === 有什么不同
同源策略 (same-origin policy)
strict模式
为何通常会认为保留网站现有的全局作用域 (global scope) 不去改变它,是较好的选择
- 减少命名冲突
- 有利于模块化
请解释什么是单页应用 (single page app), 以及如何使其对搜索引擎友好 (SEO-friendly)
单页应用是指在浏览器中运行的应用,它们在使用期间不会重新加载页面。像所有的应用一样,它旨在帮助用户完成任务,比如“编写文档”或者“管理Web服务器”。可以认为单页应用是一种从Web服务器加载的富客户端
使用服务端渲染
Promise如何使用,实现
可变对象和不可变对象
可变对象
我们知道,JavaScript中对象是弱类型的。一般情况下,可以不受限制的为对象添加属性,修改属性,删除属性。大部分情况下,我们使用的都是可变对象。
不可变对象
对应的,我们不希望代码中某些对象被任意修改,比如添加、修改、删除等。这就是我们的不可变对象。JavaScript为我们提供了一些原生方法,借助它们可以讲一些可变对象转变成不可变对象。一共有三种:不可扩展,密封,冻结。
- Object.preventExtensions(obj) 不可扩展(无法阻止深层属性的扩展)
1 |
|
Object.seal(obj) 方法可以让一个对象密封,并返回被密封后的对象。密封对象将会阻止向对象添加新的属性。另外也会 改变属性的 configurable 描述。
Object.freeze(obj) 方法可以冻结一个对象。冻结指的是不能向这个对象添加新的属性,不能修改其已有属性的值,不能删除已有属性,以及不能修改该对象已有属性的可枚举性、可配置性、可写性。也就是说,这个对象永远是不可变的。该方法返回被冻结的对象。
什么是事件循环
let var const
数组的方法
web worker
函数柯里化
创建对象的三种方法
- 构造函数:
var obj = new Object();
- 对象字面量:
var obj = {};
Object.create(obj[, otherobj])
;
深拷贝和浅拷贝
1 | var obj = { |
网页上各种高度
实现页面加载进度条
箭头函数和普通函数有什么区别
箭头函数 | 普通函数 | |
---|---|---|
写法 | var fn = () => {} | function fn() {} |
arguments | 无 | 有 |
this | 运行时向父作用域查找,直到window | 1. 作为函数调用,指向window 2. 作为对象的方法调用,指向当前对象 |
new | 不能使用 | 函数作为构造函数 |
原型属性 | 没有原型属性console.log(fn.prototype) //undefined |
有原型属性 |