DocumentType有什么用?
DOCTYPE是document type(文档类型)的简写,在web设计中用来说明你用的XHTML或者HTML是什么版本。
要建立符合标准的网页,DOCTYPE声明是必不可少的关键组成部分;除非你的XHTML确定了一个正确的DOCTYPE,否则你的标识和CSS都不会生效。
Doctype可声明三种DTD类型,分别表示严格版本、过渡版本以及基于框架的 HTML 文档。
给100个里绑定点击事件
利用事件代理, 详见我的另一篇博客:https://blog.csdn.net/Web_J/article/details/83900073
function print() {let person1={ name:"小黄" };let person2=person1
function print() {
let person1={
name:"小黄"
};
let person2=person1
console.log(person1.name)//小黄
let person3={
name:person1.name
};
person3.name="小张"
console.log(person1.name)//小黄
let person4=Object.assign({},person1)
//Object.assign()类似深拷贝,只是拷贝的是属性值。假如源对象的属性值是一个对象的引用,那么它也只指向那个引用。
person4.name="小强"
console.log(person1.name)//小黄
let person5=person2
person5.name="小马"
console.log(person1.name)//小马
}
print();
var a={x:100} function A(obj) {var b=obj b.x=200
var a={x:100}
function A(obj) {
var b=obj
b.x=200
var c=b
c={x:300} //开辟新内存
console.log(a.x);//200
console.log(b.x);//200
console.log(c.x);//300
}
A(a)
console.log(a);//{x: 200} //修改参数也会改变外面的变量
作用域
var count=10;//全局作用域 标记为f1
function add(){
var count=0;//函数全局作用域 标记为f2
return function(){
count+=1;//函数的内部作用域
alert(count);
}
}
var s=add()
s();//输出1
s();//输出2
详看:https://blog.csdn.net/Web_J/article/details/84866582
class Animal {constructor(){this.type = 'animal'}
class Animal {
constructor(){
this.type = 'animal'
}
says(say){
setTimeout(function(){
console.log(this.type + ' says ' + say) //setTimeout()的this指向window或global对象
}, 1000)
}
}
var animal = new Animal()
animal.says('hi') //undefined says hi
详看:https://blog.csdn.net/Web_J/article/details/84941963
倒计时10秒
window.onload = function(){
let i = 10;
let timer = setInterval(function(){
i<0 ? clearInterval(timer) : document.body.innerHTML = i--
},1000);
}
('b' + 'a' + + 'a' + 'a').toLowerCase()输出什么?
好吧,才疏学浅的我看到这题的答案是:baaa
先说下正确答案,以便大家跟着我一个思路:banana
既然这么说了,那这一定是错误答案了,下面我们来解析一下这个题:
1. js运算优先级和隐式转换
仔细一想,这题估计和JavaScript运算符优先级、隐式转化有关系。
于是先去MDN查了一下JavaScript运算符优先级
我先把上面代码用到的运算符和优先级列举出来:
圆括号(20)>一元正号(16)>加法(13)
好了,现在我们来解析一下这个代码:
'b' + 'a' + (+ 'a') + 'a'
一元正号的优先级高于加法,所以我们这样用括号会让这个代码更加清晰<br> 先运算优先级高的,也就是括号里面的,在与运算括号外面的
2. 一元正号 运算
这时候就涉及到第二个重要的知识点,一元正号的运算,先来看官方文档:
一元正号运算符位于其操作数前面,计算其操作数的数值,如果操作数不是一个数值,会尝试将其转换成一个数值。
尽管一元负号也能转换非数值类型,但是一元正号是转换其他对象到数值的最快方法,也是最推荐的做法,因为它不会对数值执行任何多余操作。
它可以将字符串转换成整数和浮点数形式,也可以转换非字符串值true,false和null。小数和十六进制格式字符串也可以转换成数值。
负数形式字符串也可以转换成数值(对于十六进制不适用)。如果它不能解析一个值,则计算结果为 NaN。
注意看上面的这段话:如果操作数不是一个数值,会尝试将其转换成一个数值和如果它不能解析一个值,则计算结果为 NaN
那上面代码的+ 'a'就是会变成NaN,过程如下:
'b' + 'a' + NaN + 'a'
// to
'b' + 'a' + "NaN" + 'a'
最终在调用toLowerCase函数转成小写,就变成了banana
let a = {n : 1};let b = a;a.x = a = {n: 2};
let a = {n : 1};
let b = a;
a.x = a = {n: 2};
console.log(a.x)
console.log(b.x)答案:let a = {n : 1};let b = a;a.x = a = {n: 2};console.log(a.x) console.log(b.x)_微 光的博客-CSDN博客
你知道的网页制作会用到的图片格式有哪些 ?
1.png-8 、 png-24 、 jpeg 、 gif 、 svg
2.但是上面的那些都不是面试官想要的最后答案。面试官希望听到的是Webp , Apng 。(是否有关注新技术,新鲜事物)
3.Webp: WebP 格式,姑歌(google)开发的一种旨在加快图片加载速度的图片格式。图片压缩体积⼤约只有 JPEG 的 2/3 ,并能节省流量的服务器带宽资源和数据空间。
Facebook Ebay 等知名网站已经开始测试并使用 WebP 格式。
4.在质量相同的情况下,WebP格式图像的体积要比JPEG格式图像小 40% 。
5.Apng:全称是 “Animated Portable Network Graphics” , 是PNG的位图动画扩展,可 以实现png格式的动态图⽚效果。04年诞生,但一直得不到各浏览器支持,直到
目前得到iOS safari 8 的支持,有望代替 GIF 成为下代动态图标准
实现函数柯里化(使用多个参数的一个函数转换成一系列使用一个参数的函数)
function currying(fn) {
let args_arr = [], max_length = fn.length
let closure = function (...args) {
// 先把参数加进去
args_arr = args_arr.concat(args)
// 如果参数没满,返回闭包等待下一次调用
if (args_arr.length < max_length) return closure
// 传递完成,执行
return fn(...args_arr)
}
return closure
}
function add(x, y, z) {
return x + y + z
}
curriedAdd = currying(add)
console.log(curriedAdd(1, 2)(3))
JS 分步实现柯里化函数_weixin_34329187的博客-CSDN博客
js实现栈
function ArrayStack(){
var arr = [];
//压栈操作
this.push = function(element){
arr.push(element);
}
//退栈操作
this.pop = function(){
return arr.pop();
}
//获取栈顶元素
this.top = function(){
return arr[arr.length-1];
}
//获取栈长
this.size = function(){
return arr.length;
}
//清空栈
this.clear = function(){
arr = [];
return true;
}
this.toString = function(){
return arr.toString();
}
}
单页面和多页面的区别
引入cdn字体会发生什么
字体跨域
字体文件在CDN服务器上、项目部署在自己的服务器上,字体文件就出现了跨域加载的问题。
处理这种跨域,只要设置Access-Control-Allow-Origin,允许目标域名访问就可以了,Access-Control-Allow-Origin是HTML5新增的一个特性,在资源类的域名下做如下配置(nginx的配置,apache相似处理)
location ~ .*\.(eot|ttf|ttc|otf|eot|woff|woff2|svg)(.*) { add_header Access-Control-Allow-Origin http://www.yourdomain.com; }
JS扁平化数组
flat()
默认只会“拉平”一层,如果想要“拉平”多层的嵌套数组,可以将flat()
方法的参数写成一个整数,表示想要拉平的层数,默认为1。如果不管有多少层嵌套,都要转成一维数组,可以用Infinity
关键字作为参数。
[1, 2, [3, [4, 5]]].flat()
// [1, 2, 3, [4, 5]]
[1, 2, [3, [4, 5]]].flat(2)
// [1, 2, 3, 4, 5]
[1, [2, [3]]].flat(Infinity)
// [1, 2, 3]
递归
function flatten(arr){
var result=[];
for(var i=0;i<arr.length;i++){
if(Array.isArray(arr[i])){
result=result.concat(flatten(arr[i]))
}else{
result.push(arr[i]);
}
}
return result;
}
扩展运算符
function flatten(arr) {
while(arr.some(item=>Array.isArray(item))) {
//some() 方法用于检测数组中的元素是否满足指定条件
arr = [].concat(...arr);
}
return arr;
}
js事件监听和JQ事件监听的写法
详见JS如何给ul下的所有li绑定点击事件,点击使其弹出下标和内容_微 光的博客-CSDN博客_给ul下的所有li添加点击事件
计算字符串中每个字符出现的次数
const arr="abcdaabc";
let counter = {};
for (let i = 0, len = arr.length; i < len; i++ ) {
counter[arr[i]] ? counter[arr[i]]++ : counter[arr[i]] = 1;
}
console.log(counter);// {a: 3, b: 2, c: 2, d: 1}
去除字符串中的无效字符和乱码
/**
* 请处理给定字符串:
* - 去掉无用字符和乱码, 只保留大小写英文字母, 单引号, 和空格
* - 把一个或多个连续无用字符和乱码换成一个空格
* @param str: 字符串, 例 "I'm我driving是to乱Beijing码after breakfast"
* @return str: 例 "I'm driving to Beijing after breakfast"
*/
decode=str => {
var reg = /([a-z]|[A-Z]|\'|\s)+/g // \s查找空白字符。
var b = str.match(reg) //match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。
return b.join(' ');
}
var str = "I'm我driving是to乱Beijing码after breakfast"
decode(str)
JS大数相加
let a = "9007199254740991";
let b = "1234567899999999999";
function add(a ,b){
//取两个数字的最大长度
let maxLength = Math.max(a.length, b.length);
//用0去补齐长度
a = a.padStart(maxLength , 0);//"0009007199254740991" padStart()用于头部补全,padEnd()用于尾部补全
b = b.padStart(maxLength , 0);//"1234567899999999999"
//定义加法过程中需要用到的变量
let t = 0;
let f = 0; //"进位"
let sum = "";
for(let i=maxLength-1 ; i>=0 ; i--){
t = parseInt(a[i]) + parseInt(b[i]) + f;
f = Math.floor(t/10);
sum = t%10 + sum;
}
if(f == 1){
sum = "1" + sum;
}
return sum;
}
git版本回退
git reset --hard id
Function.prototype.a = 'a';Object.prototype.b = 'b';function Person(){};
Function.prototype.a = 'a';
Object.prototype.b = 'b';
function Person(){};
var p = new Person();
console.log('p.a: '+ p.a); // p.a: undefined
console.log('p.b: '+ p.b); // p.b: b
不少人第一眼看上去就觉得很疑惑,p不是应该继承了Function原型里面的属性吗,为什么p.a返回值是undefined呢?
其实,只要仔细想一想就很容易明白了,Person函数才是Function对象的一个实例,所以通过Person.a可以访问到Function原型里面的属性,但是new Person()返回来的是一个对象,它是Object的一个实例,是没有继承Function的,所以无法访问Function原型里面的属性。但是,由于在js里面所有对象都是Object的实例,所以,Person函数可以访问到Object原型里面的属性,Person.b => 'b'
qiankun的原理
- HTML Entry 接入方式,让你接入微应用像使用 iframe 一样简单。
- 样式隔离,确保微应用之间样式互相不干扰。
- JS 沙箱,确保微应用之间 全局变量/事件 不冲突。
为什么不用iframe
- url 不同步。浏览器刷新 iframe url 状态丢失、后退前进按钮无法使用。
- UI 不同步,DOM 结构不共享。想象一下屏幕右下角 1/4 的 iframe 里来一个带遮罩层的弹框,同时我们要求这个弹框要浏览器居中显示,还要浏览器 resize 时自动居中..
- 全局上下文完全隔离,内存变量不共享。iframe 内外系统的通信、数据同步等需求,主应用的 cookie 要透传到根域名都不同的子应用中实现免登效果。
- 慢。每次子应用进入都是一次浏览器上下文重建、资源重新加载的过程。
arr = [1,2,3,4],如何得到arr.fn = [1,2,3,4,1,2,3,4]?
1.arr.concat(arr) //concat()方法生成了一个新的数组,并不改变原来的数组。
2.arr.push.apply(arr,arr) //使用apply劫持数组的push方法
3.[...arr,...arr] //扩展运算符(...)
杨辉三角的JS实现
function compute(m, n) {
if (n == 0) {
return 1; //每行第一个数为1
} else if (m == n) {
return 1; //最后一个数为1
} else {
//其余都是相加而来
return compute(m - 1, n - 1) + compute(m - 1, n);
}
}
function yanghui(n) {
//杨辉三角,N为行数
for (var i = 0; i < n; i++) {
//一共N行
for (var j = 0; j <= i; j++) {
//每行数字的个数即为行号、例如第1行1个数、第2行2个数
document.write(compute(i, j) + " ");
}
document.write("<br>");
}
}
yanghui(15)
二分查找
可用递归和非递归两种方式,折半查找