文章目录
- onclick 与 addEventListner的区别
- JavaScript事件环机制
- JS中申明变量的方式
- XSS攻击
- 编写一个Emitter事件分发类,有on、off、trigger、once方法
- 编写一个函数,用于从cookie里面获取数据
- HTML5提供哪两种存储的API
- 前端存储
- 有如下HTML代码,实现点击删除链接后,删除当前点击所在的li项
- 网站的登录态是如何保持的,一个完整的登录流程是怎样实现的?
- requestAnimationFrame方法是做什么用的,应用场景有哪些?
- DOM的onload和DOMContentLoaded事件有什么区别?
- 在Object.defineProperty(obj, prop, descriptor) ,descriptor参数可以设置的属性有?
- JS中检测数据类型
- 以下代码能把json格式的字符 {} 转成json对象的有?
- 以下是支持正则表达式的String对象的方法有?
- 数组的下列方法,结果返回true的有?
- 以下执行结果不是number类型的有
- 对象,原型的理解
- 跨域解决方法
- 阻止冒泡
- 防止表单提交
- 对象的深度复制和浅度复制
- JS中改变this指向
- 一数组里面存了表达式,依次执行,前一项的结果作为后一项的输入参数
- 调换位置使得差最大
- JS循环中,结束当前循环进入下一循环的关键字
- HTML知识点
- 协议知识点
- 正则表达式知识点
- CSS知识点
- 用HTML和css3编写代码,实现一个圆形左右无限循环来回移动。
- 其他莫名其妙的题
onclick 与 addEventListner的区别
<ul class="list">
<li>
aa点击
</li>
</ul>
var list = document.getElementsByClassName("list")[0];
list.addEventListener("click", function(e){
console.log("click0");
});
var li = document.getElementsByTagName("li")[0];
console.log("li", li);
li.onclick = function (e){
console.log("click1");
}
list.onclick = function(){
console.log("click3");
}
// click1 click0 click3
var list = document.getElementsByClassName("list")[0];
list.onclick = function(){
console.log("click3");
}
list.addEventListener("click", function(e){
console.log("click0");
});
var li = document.getElementsByTagName("li")[0];
console.log("li", li);
li.onclick = function (e){
console.log("click1");
}
// click1 click3 click0
JavaScript事件环机制
原文链接
javascript是一门单线程语言
,Event Loop
是javascript的执行机制
JS有 同步任务 和 异步任务 ,异步,其实都是用同步的方法去模拟的。
JS也有
macro-task(宏任务)
- 包括整体代码script
- setTimeout
- setInterval
- setImmediate
micro-task(微任务)
- Promise
- process.nextTick
setTimeout(function(){
console.log('1')
});
new Promise(function(resolve){
console.log('2');
resolve();
}).then(function(){
console.log('3')
});
console.log('4');
// 2, 4, 3, 1
JS中申明变量的方式
- var:
1.函数作用域,不能跨函数
var b2 = {};
function fn1 () {
console.log(b2); // undefined
var b2 = [];
console.log(b2); // []
}
function fn2 () {
console.log(b2); // {}
}
fn1();
fn2();
{
var b3 = 111;
}
console.log(b3); //111
2.变量提升
console.log(a); //undefined
var a = 123;
- let:
1.不存在变量提升
console.log(b); //Cannot access 'b' before initialization
let b = {};
2.不能重复定义
let b = {};
let b = [];
console.log(b); // Identifier 'b' has already been declared
3.不能跨块,只能用于块级作用域
{
let c = 0;
}
//console.log(c,222); //报错
let c = 2;
console.log(c,222); // 2 222
4.存在暂时性死区
无论在块中的任何地方声明了一个变量,那么在这个块级作用域中,任何使用这个名字的变量都是指这个变量,无论外部是否有其他同名的全局变量——规范代码
var a = 1;
if(1){
console.log(a); //Cannot access 'a' before initialization
let a = 2;
}
var a = 1;
if(1){
console.log(a); //1
}
- const:
1.只读属性,不可修改,必须初始化
2.其他跟 let 一样
const b2 = {};
function fn1 () {
console.log(b2); // 报错
const b2 = [];
}
function fn2 () {
console.log(b2, 111); // {} 111
}
//fn1();
fn2();
XSS攻击
原文链接
XSS攻击的类型
- 存储型
- 反射型
- dom-xss
编写一个Emitter事件分发类,有on、off、trigger、once方法
function EventEmitter(){
this.tasks = {};
}
EventEmitter.prototype = {
constructor:EventEmitter,
on: function(name,fn){
if(!this.tasks[name]){
this.tasks[name] = [];
}
this.tasks[name].push(fn);
},
once: function(name,fn){
if(!this.tasks[name]){
this.tasks[name] = [];
}
fn.tag = 'once'
this.tasks[name].push(fn);
//this.tasks[name][this.tasks[name].length-1].tag = 'once';
},
emit: function(name,args){
if(this.tasks[name] instanceof Array){
let task = this.tasks[name];
for(let i = 0,len = task.length;i<len;i++){
args = Array.prototype.slice.call(arguments,1);
task[i].apply(this,args);
// debugger
if(task[i].tag === 'once'){
this.tasks[name].splice(i,1)
}
}
}
},
remove: function(name,fn){
if(this.tasks[name] instanceof Array){
for(var i = 0,len = this.tasks[name].length;i<len;i++){
if(fn === this.tasks[name][i]){
break;
}
}
if(i<len){
this.tasks[name].splice(i,1);
}
}
}
}
编写一个函数,用于从cookie里面获取数据
//获取cookie
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
/**
*以下内容为扩展
*/
//设置cookie
function setCookie(cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
var expires = "expires="+d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
//检测cookie
function checkCookie() {
var user = getCookie("username");
if (user != "") {
alert("Welcome again " + user);
} else {
user = prompt("Please enter your name:", "");
if (user != "" && user != null) {
setCookie("username", user, 365);
}
}
}
考点:前端数据存储
HTML5提供哪两种存储的API
localStorage(本地存储)和sessionStorage(会话存储)
考点:前端数据存储
前端存储
- cookies
- session
- webStorage
- localStorage(本地存储)
- sessionStorage(会话存储)
- 本地数据库
有如下HTML代码,实现点击删除链接后,删除当前点击所在的li项
<ul class="list">
<li>
aa<a href="/">删除</a>
</li>
<li>
bb<a href="/">删除</a>
</li>
<li>
cc<a href="/">删除</a>
</li>
</ul>
考点:查找元素、监听事件、阻止默认操作、删除节点
var list = document.querySelector('.list');
list.addEventListener('click',function(event){
event.preventDefault();
if (event.target.tagName === 'A'){
var li = event.target.parentNode;
list.removeChild(li);
}
});
event.target 里面包含了很多的属性,与节点有关的有:
- 包含文本节点(text):childNodes,firstChild,lastChild,nextSibling,previousSibling,parentNode
- 不包含文本节点:children,firstElementChild,lastElementChild,nextElementSibling,previousElementSibling,parentElement,childElementCount
网站的登录态是如何保持的,一个完整的登录流程是怎样实现的?
通过cookies来保持的,cookie面面存储token,每次请求到后端服务器都会带上token。从而验证用户是否登录。
输入用户、密码 —> 点击登录,发送到服务端 —> 服务端验证密码生成token —> 写入到cookies,返回成功
1.客户端请求后台登录接口。
2.后台验证通过后,将用户的登录状态保存至cookie并写入客户端。
3.客户端再次登录网站,请求login接口时,后台直接从客户端获取到该用户写入cookie的登录状态。
4.通过对该状态的验证,确认用户是否需要再次登录。
5.如cookie过期,则跳转至登录页;如未过期,则直接显示为已登录状态。
requestAnimationFrame方法是做什么用的,应用场景有哪些?
考点:JS动画优化
解析:浏览器可以优化并行的动画动作,更合理地重新排列动画序列,并把能够合并的动作放在一个渲染周期内完成,从而呈现出更流畅的动画效果,节省CPU。
应用场景:游戏,动画
DOM的onload和DOMContentLoaded事件有什么区别?
考点:浏览器的渲染过程
解析:
当onload 事件触发时,页面上所有的DOM,样式表,脚本,图片,flash都已经加载完成了
当DOMContentLoaded 事件触发时,仅当DOM加载完成,不包括样式表,图片,flash
在Object.defineProperty(obj, prop, descriptor) ,descriptor参数可以设置的属性有?
A.configurable
B.enumerable
C.length
D.value
解析:ABD
属性描述对象提供6个元属性。
- (1)value
value存放该属性的属性值,默认为undefined。 - (2)writable
writable存放一个布尔值,表示属性值(value)是否可改变,默认为true。 - (3)enumerable
enumerable存放一个布尔值,表示该属性是否可枚举,默认为true。如果设为false,会使得某些操作(比如for…in循环、Object.keys())跳过该属性。 - (4)configurable
configurable存放一个布尔值,表示“可配置性”,默认为true。如果设为false,将阻止某些操作改写该属性,比如,无法删除该属性,也不得改变该属性的属性描述对象(value属性除外)。也就是说,configurable属性控制了属性描述对象的可写性。 - (5)get
get存放一个函数,表示该属性的取值函数(getter),默认为undefined。 - (6)set
set存放一个函数,表示该属性的设值函数(setter),默认为undefined
深入浅出Object.defineProperty()
下面coding内容是对这篇文章的小小探索
let person = {};
Object.defineProperty(person, "name",{
value: "Jack",
// writable: true
});
person.name = "rose";
console.log(person.name); //Jack
let Person = {};
let temp = null;
Object.defineProperty(Person, 'name', {
get: function () {
console.log("get");
return temp
},
set: function (val) {
console.log("set");
temp = val // 去掉这句,name 值为undefined
}
});
Person.name = "Jack";
console.log("name", Person.name);
console.log("temp", temp);
let Person = {};
Object.defineProperty(Person, 'name', {
value: "Jack",
configurable: false
});
Person.name = "rose";
console.log("name", Person.name); //name Jack
let Person = {};
Object.defineProperty(Person, 'name', {
value: "Jack",
configurable: true
});
Person.name = "rose";
console.log("name", Person.name); //name Jack
let Person = {};
Object.defineProperty(Person, 'name', {
value: "Jack",
configurable: false,
writable: true
});
Person.name = "rose";
console.log("name", Person.name); //name rose
preventExtensions方法只是让object不可添加新的属性,但可以对原来的属性进行删,改
let Person = {name : "Jack"};
Object.preventExtensions(Person);
Person.name = "rose";
console.log("name", Person.name); //rose
delete Person.name;
console.log("name", Person.name); //undefined
JS中检测数据类型
-
typeof
-
instanceof
-
isNaN
-
isFinite
以下代码能把json格式的字符 {} 转成json对象的有?
A.JSON.parse(‘{}’)
B.JSON(’{}’)
C.(new Function(“return {}”))()
D.eval(‘{}’)
解析:
A. JSON.parse方法返回的是json对象
B. JSON(’{}’)
C. (new Function(“return {}”))():执行函数,返回{}
D. eval方法是对可计算的字符串进行计算,若传入不是可计算的字符串,会产生一些意想不到的结果。
以下是支持正则表达式的String对象的方法有?
A.replace
B.split
C.test
D.exec
数组的下列方法,结果返回true的有?
A.[0,1,2,3,4].every(Number)
B.[0,1,2,3,4].some(Number)
C.[0,1,2,3,4].map(Number)
D.[0,1,2,3,4].forEach(Number)
注意,[0,1,2,3,4].every(Number)返回的是false,[1,2,3,4].every(Number)返回的是true
[0,1,2,3,4].every(Number) // false
[1,2,3,4].every(Number) // true
[{},[],function(){},null].every(Object) // true
以下执行结果不是number类型的有
A.‘a’ + 1
B.1/0
C.Symbol(0)
D.Number(‘1.9999’).toFixed(2)
解析:
A.a1
B. Infinity 无限,属于Number类型
C.Symbol对象
D.toFixed方法返回字符串
对象,原型的理解
function A(){}
function B(a){
this.a = a;
}
function C(a){
if(a){
this.a = a;
}
}
A.prototype.a = 1;
B.prototype.a = 1;
C.prototype.a = 1;
console.log(new A().a) //1
console.log(new B().a)// undefined
console.log(new C(2).a)// 2
function Foo(){
return this;
}
Foo.getName = function(){
console.log("1");
}
Foo.prototype.getName= function(){
console.log("2");
}
new Foo.getName() //1
new Foo().getName(); //2
跨域解决方法
jsonp ,iframe,cors,服务器代理
阻止冒泡
- window.event.cancelBubble = true
- stopPropagation()
防止表单提交
window.event.returnValue = false;
对象的深度复制和浅度复制
var obj1 = {a :1, b: {value: 2}, c: 3};
var obj2 = Object.assign(obj1, {c: 0});
obj2.b.value = 0;
console.log(obj2.c); //0
console.log(obj1.b.value); //0
console.log(obj1 === obj2); //true
JS中改变this指向
- bind()
返回一个函数体
var obj = {};
function fn1(){
console.log("this", this);
}
fn1.bind(obj)(); // 指向obj
fn1(); // window
- call()
立即执行函数
语法:functionObject.call ( obj, [param1, param2 ……] );
分别接收参数
var obj = {};
function fn1(){
console.log("this", this);
}
fn1.call(obj); // 指向obj
fn1(); // window
- apply()
立即执行函数
functionObject.apply ( obj, [[param1, param2 ……]] )
接受数组形式的参数
var obj = {};
function fn1(){
console.log("this", this);
}
fn1.apply(obj); // 指向obj
fn1(); // window
var person = {
fullName: function(city, country) {
return this.firstName + " " + this.lastName + "," + city + "," + country;
}
}
var person1 = {
firstName:"John",
lastName: "Doe"
}
person.fullName.apply(person1, ["Oslo", "Norway"]);
- 箭头函数
- 对象的函数赋值到其他变量中
bind(),call(),apply()的异同:
- 三个都是不会影响原函数
- 三个函数的第一个参数都是 this 的指向
- bind是返回一个新函数体,需要再调用一次才会执行,call 和 apply 则是立即执行函数
一数组里面存了表达式,依次执行,前一项的结果作为后一项的输入参数
functionArr = [a => a * 2, a => a - 3, a => a /5]
apply(functionArr)(5) 的结果是1.4
apply(functionArr)(4)的结果是 1
apply函数返回一个函数,一次执行functionArr,前一项的结果作为后一项的参数a
// 没有思路
调换位置使得差最大
实现一个函数,对数字进行一次调换,使得两者之差的绝对值最大。
例如,98668 ,变成 98866。
// 没有明确思路
JS循环中,结束当前循环进入下一循环的关键字
A.continue
B.break
C.return
D.with
答案:continue
- continue,用于结束本轮循环进入下一轮循环
- break,用于结束循环体
- return ,用于结束方法,方法内的循环体也会被结束。单在循环体内使用return关键字会报错。
- with,
HTML知识点
各种标签,标签的属性啊等等……
Form标签的()属性用于设置表单提交时向何处发送表单数据
答案:action
转义编码
第一列 | 第二列 | 第三列 |
---|---|---|
< | < | 小于号或显示标记 |
\gt; | > | 大于号或显示标记 |
& | & | 可用于显示其他特殊字符 |
" | " | 引号 |
® | ® | 已注册 |
© | © | 版权 |
™ | ™ | 商标 |
  | 空格 | |
  | 空格 | |
| 空格 |
以下属于Audio/Video的方法有?
A.load()
B.play()
C.pause()
D.stop()
答案:ABC
哪些是css属性position可以设置的值
已下哪个方法能最好的清除浮动问题
A.让父标签也浮动
B.写死父标签的height属性
C.忘了
D.忘了
考点:清除浮动
协议知识点
包括http协议,状态码等等……
HTTPS协议从握手到传输数据,用到了对称和非对称密码
正确
TCP/IP结构对应OSI
1、物理层:
主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。它的主要作用是传输比特流(就是由1、0转化为电流强弱来进行传输,到达目的地后在转化为1、0,也就是我们常说的数模转换与模数转换)。这一层的数据叫做比特。
2、数据链路层:
定义了如何让格式化数据以进行传输,以及如何让控制对物理介质的访问。这一层通常还提供错误检测和纠正,以确保数据的可靠传输。
3、网络层:
在位于不同地理位置的网络中的两个主机系统之间提供连接和路径选择。Internet的发展使得从世界各站点访问信息的用户数大大增加,而网络层正是管理这种连接的层。
4、传输层:
定义了一些传输数据的
协
议
和
端
口
号
\color{red}{协议和端口号}
协议和端口号 (HTTP端口80等),如:
TCP(transmission control protocol –传输控制协议,传输效率低,可靠性强,用于传输可靠性要求高,数据量大的数据)
UDP(user datagram protocol–用户数据报协议,与TCP特性恰恰相反,用于传输可靠性要求不高,数据量小的数据,如QQ聊天数据就是通过这种方式传输的)。 主要是将从下层接收的数据进行分段和传输,到达目的地址后再进行重组。常常把这一层数据叫做段。
5、会话层:
通过传输层(端口号:传输端口与接收端口)建立数据传输的通路。主要在你的系统之间发起会话或者接受会话请求(设备之间需要互相认识可以是IP也可以是MAC或者是主机名)
6、表示层:
可确保一个系统的应用层所发送的信息可以被另一个系统的应用层读取。例如,PC程序与另一台计算机进行通信,其中一台计算机使用扩展二一十进制交换码(EBCDIC),而另一台则使用美国信息交换标准码(ASCII)来表示相同的字符。如有必要,表示层会通过使用一种通格式来实现多种数据格式之间的转换。
7、应用层:
是最靠近用户的OSI层。这一层为用户的应用程序(例如电子邮件、文件传输和终端仿真)提供网络服务。
http发展历史
版本 | 产生时间 | 内容 |
---|---|---|
HTTP/0.9 | 1991 | 不涉及数据包传输,服务器只能回应HTML格式的字符串,GET 请求服务器发送完毕,就关闭TCP连接 不支持MIM类型 |
HTTP/1.0 | 1996 | 传输内容格式不限制,GET、POST、HEAD 请求每次通信都必须包括数据,头信息(用来描述一些元数据) 增加 状态码、多字符集支持、多部分发送、权限、缓存、内容编码 |
HTTP/1.1 | 1997 | GET、POST 、HEAD、PUT、DELETE、PATCH、 OPTIONS、CONNECT 持久连接(长连接)、节约带宽、HOST域、管道机制、分块传输编码 |
HTTP/2 | 2015 | 多路复用、服务器推送、头信息压缩、二进制协议等 |
HTTP/1.0 使得互联网不仅可以传输文字,还能传输图像、视频、二进制文件;为互联网的大发展奠定了基础。
持久连接
(persistent connection):
即TCP连接默认不关闭,可以被多个请求复用,不用声明Connection: keep-alive。客户端和服务器发现对方一段时间没有活动,就可以主动关闭连接。不过,规范的做法是,客户端在最后一个请求时,发送Connection: close,明确要求服务器关闭TCP连接
管道机制
(pipelining)
即在同一个TCP连接里面,客户端可以同时发送多个请求。这样就进一步改进了HTTP协议的效率。举例来说,客户端需要请求两个资源。以前的做法是,在同一个TCP连接里面,先发送A请求,然后等待服务器做出回应,收到后再发出B请求。管道机制则是允许浏览器同时发出A请求和B请求,但是服务器还是按照顺序,先回应A请求,完成后再回应B请求。
分块传输编码
对于一些很耗时的动态操作,服务器需要等到所有操作完成,才能发送数据,显然这样的效率不高。更好的处理方法是,产生一块数据,就发送一块,采用"流模式"(stream)取代"缓存模式"(buffer)
以下是http协议的请求方法的有
A.REMOVE
B.POST
C.GET
D.HEAD
解析:BCD
http参考资料
HTTP是超文本传输协议,其定义了客户端与服务器端之间文本传输的规范。
HTTP
默认使用80
端口,这个端口指的是服务端的端口,而客户端使用的端口是动态分配的。
HTTPS
的默认端口为443
,如果使用80端口访问HTTPS协议的服务器可能会被拒绝。
数据库的操作无非就是增删查改。
请求方法 | 描述 |
---|---|
POST | 增 CREATE |
DELETE | 删 DELETE |
GET | 查 SELECT |
PUT | 改 UPDATE 客户端提供改变后的完整资源 上传指定的 URI 表示 |
OPTIONS | 返回服务器支持的 HTTP 方法 |
HEAD | 与 GET 相同,但只返回 HTTP 报头,不返回文档主体 |
CONNECT | 把请求连接转换到透明的 TCP/IP 通道 |
PATCH |
1)方法名称是区分大小写的,当某个请求所针对的资源不支持对应的请求方法的时候,服务器应当返回状态码405(Mothod Not Allowed);当服务器不认识或者不支持对应的请求方法时,应返回状态码501(Not Implemented)。
2)HTTP服务器至少应该实现GET和HEAD/POST方法,其他方法都是可选的,此外除上述方法,特定的HTTP服务器支持扩展自定义的方法。
http的状态码
- 1xx: 信息
- 2xx: 成功
- 3xx: 重定向
- 4xx: 客户端错误
- 5xx: 服务器错误
状态码 | 含义 |
---|---|
301 | 永久转移 |
302 | 暂时转移 |
305 | 使用代理 |
403 Forbidden | 禁止访问 |
404 Not Found | 资源或者文件未找到 |
405 Method Not Allowed | 请求中指定的方法不被允许 |
正则表达式知识点
正则表达式的元字符()用于匹配一个非数字字符。
答案:\D
CSS知识点
px、em、rem、vh、vw的区别是什么?
- px :代表物理屏幕上能显示出的最小的一个点
- em:是相对于父级的字体大小,如果父级没有设定,找父父级,直到根元素
- rem:是相对于HTML根元素的字体大小
- vh , vw:相对于视窗的高度和宽度
- 1vh 等于1/100的视窗高度
- 1vh 等于1/100的视窗宽度
用HTML和css3编写代码,实现一个圆形左右无限循环来回移动。
考点:CSS动画
其他莫名其妙的题
广度优先搜索和深度优先搜索用到的数据结构
广度:队列
深度:栈
172.29.128.0/19有多少个IP地址
/19表示前19位为网络地址
IP地址:213