//1、填写输出顺序:
for (var i = 3; i > 0; i--) {
setTimeout(() => console.log(i), 1);
}
//输出:333
使用 var:
每一次for循环的时候,setTimeout都执行一次, 但是里面的函数没有被执行,而是被放到了任务队列里面,等待执行, for循环了4次,就放了4次,当主线程执行完成后,才进入任务队列里面执行。
使用 let:
for循环头部的let不仅将i绑定到for循环块中, 它也将其重新绑定到 循环体的每一次迭代 中,确保上一次迭代结束的值重新被赋值。 setTimeout里面的function()属于一个新的域, 通过 var 定义的变量是无法传入到这个函数执行域中的, 而通过使用 let 来声明块变量,这时候变量就能作用于这个块, 所以 function就能使用 i 这个变量了; 这个匿名函数的参数作用域 和 for参数的作用域 不一样。
//2、填写运行结果:
function Page() {
return this.hosts;
}
Page.hosts = ['h1'];
Page.prototype.hosts = ['h2'];
const p1 = new Page();
const p2 = Page(); //p2=this.hosts this=Page()未声明,函数调用后就在内存中删去
console.log(p1.hosts); //undefined 构造函数里没有定义host属性
console.log(p2.hosts); //typeError Cannot read property 'hosts' of undefined
// 3、填写运行结果:
var value = 20;
(function () {
console.log(name); //undefined var name已声明,未赋值
console.log(value); //undefined
var name = 'local value';
let value = 21; //不能提升
})();
//4、请实现函数log(),将一个对象扁平化的输出到控制台。如:
log({
foo : ‘test’,
bar : {
id : 123,
name : ‘tx’
}
})
输出:
foo=test
bar.id=123
bar.name=tx
Object.flatten = function(obj){
var result = {};
function flatten(obj) {
var result = {};
function process(key, value) {
if (Object(value) !== value) {
if (key) {
result[key] = value;
}
} else if (Array.isArray(value)) {
for (var i = 0, len = value.length; i < len; i++) {
process(key + "[" + i + "]", value[i]);
}
if (value.length === 0 && key) {
result[key] = [];
}
} else {
var isEmpty = true;
for (var prop in value) {
isEmpty = false;
process((key ? key + "." : key) + prop, value[prop]);
}
if (isEmpty && key) {
result[key] = {};
}
}
}
process("", obj);
return result;
————————————————
版权声明:本文为优快云博主「denlaku」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/denlaku/article/details/51736874
对象扁平化的递归高级函数写法(ES6):
var flutter = (obj,fn)=>{
for(var proverty in obj){
if(obj.hasOwnProperty(proverty)){
if(obj[proverty] instanceof Object){
flutter(obj[proverty],(k,v)=>{console.log(proverty+"."+k+":"+v)});
}
else
fn(proverty,obj[proverty]);
}
}
}
var a= {foo:"test",
bar : {
id : 123,
name : "test"}
}
flutter(a,(k,v)=>{console.log(k+":"+v)});
-
箭头函数的特性及使用注意事项
- 箭头函数的arguments和this都在编译的时候绑定在父作用域上(没有自己的this和arguments.故向上寻找),不能改变
- 不能用作类的构造函数,new调用会报错
-
node.js
- require 模块是异步操作
- 适用于高并发,I\O密集型,少业务逻辑的应用
- exports和module.exports的区别:
-exports是module.exports的一个引用,是辅助工具
-当module.exports没有任何的属性和方法时,exports接受到的属性和方法会赋予给module,exports, 已有方法时则无效
-最终导出的还是module.exports
-
DOMcontentLoaded 和 load的区别
- DOMcontentLoaded 是当浏览器解析渲染完html文本后触发的钩子
- load是整个页面的所有内容(html文本内容解析渲染完毕+图片音像资源请求加载完毕)
- (dom树+CSS树=>渲染树(途中html文本解析会被JS阻断,JS又会等待CSS树))=>DOMcontentLoded =>图片资源加载 => load
-
静态Web页面优化
- 避免使用
document.write()
通过JS让页面加载资源,这会造成阻塞,浏览器页面渲染会等待加载再渲染 - 使用HTTP/2使请求优化(HTTP2针对HTTP1.x进行了性能优化)
- 静态文件使用CDN转载,让资源放在离用户较近的服务器站点上,减少DNS解析跳转
- 使用passive的事件监听器
target.addEventListener(type,listener,{passive,true})
来告诉浏览器该listener不会使用preventDefault来阻止默认事件行为(如<a>
的跳转),浏览器可以不用等待(监听器执行以得知是否有阻止),可以直接生成事件了 - 懒加载\雪碧图等
- 较小的图片(小于4/8KB) 用inline image方式(src=“data:/”)减少请求)
- 避免使用
-
RSA,SHA,DES,BASE64哪个不可逆?
RSA是非对称加密,加密解密采用不同的密钥,虽然非对称,但是只要拿到密钥,就能解密,所以可逆。
DES是对称加密,加密解密采用同一个密钥,拿到密钥后就可以解密,所以可逆。
BASE64只是简单的编码,没有密钥,算法是公开的,可逆。
SHA是哈希函数,一般用于产生摘要,是单向散列函数,不可逆。 -
减少页面Reflow次数
-用innerHtml更新子节点
-批量添加DOM节点时 用DocumentFragment
前端页面减少Reflow具体方法 -
cookie里可包含的信息
-用户主题设置
-令牌信息 但一般放Token
session not cookie-登陆用户的临时状态 如脚本中临时使用变量的值+权限配置 -
XSS攻击
-用户非法输入脚本语句的攻击
-防御
-对用户输入进行过滤编码(ajax中间件)
-使用内容安全策略(添加一个HTTP请求头,确保所有的脚本都同站) -
CSRF 伪造请求攻击
-使用referer确保跳转的原页面不是恶意页面
function fn(a) {
a++;
console.log(a);
}
var x = 10;
fn(x);
console.log(x);
// 11
// 10
当我们声明一个变量a的时候, 会在栈里面开辟出一块新的内存空间, 用来存放这个变量a的数值, 当这个变量a存储的数值发生改变时, 栈空间里的对应那块内存里的数据也会发生改变, 此时如果又声明了一个变量b, 并把变量a赋值给变量b时, 在栈里面又会新开辟出一块空间, 用来存放变量b存储的数值, 而这个数值, 是变量a传递给他的, 因此, 此时两个变量分别对应两块内存空间, 存储的值是相同的, 因此, 当变量a发生改变时, 并不会影响到变量b所拥有的那块内存空间, 所以变量b是不会改变的
linux用户权限数字设定法
-
语法
chmod abc 文件名 //其中a,b,c各为一个数字,分别表示User、Group、及Other的权限。
第一个数字表示文件所有者的权限第二个数字表示与文件所有者同属一个用户组的其他用户的权限
第三个数字表示其它用户组的权限。
权限分为三种:读(r=4),写(w=2),执行(x=1)。综合起来还有可读可执行(rx=5=4+1)、可读可写(rw=6=4+2)、可读可写可执行(rwx=7=4+2+1)。
-
实例
chmod 755 abc.log
chmod 4755 abc.log
1.文件所有者可读可写可执行
2.与文件所有者同属一个用户组的其他用户可读可执行
3.其它用户组可读可执行
chmod 4755与chmod 755 的区别在于开头多了一位,这个4表示其他用户执行文件时, 具有与所有者相当的权限。
<script></script>
defer
异步加载,但页面渲染到最后DOMContentLoaded
所以元素执行完毕后再执行脚本代码,最符合优化async
异步加载,加载完后会立即执行脚本代码(执行的时候不是异步的),执行时会阻塞DOM渲染- 默认:加载和执行都不是异步的,渲染阻塞最厉害
less/sass
颜色混合:
multiply(color1,color2)
将两种颜色相乘,会返回跟暗的颜色(颜料混合)
screen(1,2)
将两种颜色相乘,返回更明亮的颜色(色光混合)
- 变量提升相关题目
if(!"a" in window){
var a = 1
};
alert(a)//undefined
var a = 1
这类声明和赋值混合的语句,JS编译的时候会将var a
变量声明提升到所有语句的前面,于是上面的语句就相当于
var a
if(!"a" in window){//
a = 1
};
alert(a)//undefined
window 里已经有变量a,故if下面的赋值语句不会被执行
flex 布局
// 垂直居中,水平分布两侧
// parent 1000px
// child 100px
css 画一个高为 30px ,底为 60px 的三角形
<body>
<div id='excemple'></div>
</body>
<style>
#excemple{
border-left: 20px transparent red;
border-right: 20px solid transparent;
border-bottom: 20px solid blue;
background-color:red;
}
</style>
闭包概念
var value = 1;
function foo() {
console.log(value);
}
function bar() {
var value = 2;
foo();
}
bar();//1
-----
var foo = {
bar: function () {
return this;
}
}
foo.bar(); //[bar]
----
const fn = foo.bar;
fn();//[window/global]
-------
function get() {
// 请补全函数参数和实现逻辑
//将选取字符串中的`[]`替换为'.',再进行分隔,随后遍历递归利用[]取值的函数进行逐层取值
}
const obj = { selector: { to: { toutiao: 'FE coder' } }, target: [1, 2, { name: 'byted' }] };
// 运行代码 get(obj, 'selector.to.toutiao', 'target[0]', 'target[2].name')
// 输出结果:// ['FE coder', 1, 'byted']