19、怎样添加、移除、移动、复制、创建和查找节点? |
---|
1)创建新节点 | createDocumentFragment() //创建一个DOM片段 createElement() //创建一个具体的元素 createTextNode() //创建一个文本节点 | 2)添加、移除、替换、插入 | appendChild() //添加 removeChild() //移除 replaceChild() //替换 insertBefore() //插入 | 3)查找 | getElementsByTagName() //通过标签名称 getElementsByName() //通过元素的Name属性的值 getElementById() //通过元素Id,唯一性 |
20、浏览器的内核分别是什么? |
---|
IE: trident内核 Firefox:gecko内核 Safari:webkit内核 Opera:以前是presto内核,Opera现已改用Google Chrome的Blink内核 Chrome:Blink(基于webkit,Google与Opera Software共同开发) |
21、数组(必考) |
---|
数组方法 |
---|
concat()连接两个或更多的数组,并返回结果。
join()把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔。
pop()删除并返回数组的最后一个元素
push()向数组的末尾添加一个或更多元素,并返回新的长度。
reverse()颠倒数组中元素的顺序。
shift()删除并返回数组的第一个元素
slice()从某个已有的数组返回选定的元素
sort()对数组的元素进行排序
splice()删除元素,并向数组添加新元素。
toSource()返回该对象的源代码
toString()把数组转换为字符串,并返回结果。
toLocaleString()把数组转换为本地数组,并返回结果。
unshift()向数组的开头添加一个或更多元素,并返回新的长度。
valueOf()返回数组对象的原始值
join()把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔。
pop()删除并返回数组的最后一个元素
push()向数组的末尾添加一个或更多元素,并返回新的长度。
reverse()颠倒数组中元素的顺序。
shift()删除并返回数组的第一个元素
slice()从某个已有的数组返回选定的元素
sort()对数组的元素进行排序
splice()删除元素,并向数组添加新元素。
toSource()返回该对象的源代码
toString()把数组转换为字符串,并返回结果。
toLocaleString()把数组转换为本地数组,并返回结果。
unshift()向数组的开头添加一个或更多元素,并返回新的长度。
valueOf()返回数组对象的原始值 |
一个数组 par 中存放有多个人员的信息,每个人员的信息由年龄 age 和姓名 name 组成,如{age: 2, name: 'xx'}。请写一段 JS 程序,对这个数组按年龄从小到大进行排序。 |
---|
- var par=[{name:'a',age:1},{name:'b',age:2},{name:'c',age:3}];
par.sort(function(arr1, arr2) { return arr2.age - arr1.age; }); console.log(par); -
|
升序 (x,y表示数组中的任意两个元素,若return > 0,则y前x;若reutrn < 0 ,则x前y后;当x=y时存在浏览器兼容。简单来说:就是,x-y是按照从小到大排序,y-x是按照从大到小排序。) |
---|
var array=[1,80,4,33,21,55];
array.sort(function (x,y) {
return x-y;
});
console.log(array); |
降序 |
---|
var array=[1,80,4,33,21,55];
array.sort(function (x,y) {
return y-x;
});
console.log(array); |
22、完成foo()函数的内容,要求能弹出对话框提示当前选中的是第几个单选框 |
---|
<html> <head> <meat http-equiv=”Content-Type”content=”text/html; charset=utf-8”> </head> <body> <script type="text/script> function foo() { }; </script> <form name=”form1” οnsubmit=”retuen foo()”> <inputtype=”radio” name = “radioGroup”> <input type=”radio” name = “radioGroup”> <inputtype=”radio” name = “radioGroup”> <input type=”radio” name = “radioGroup”> </form> </body> </html> var a=document.getElementsByTagName('input');
function foo() {
for(var i=0;i<a.length;i++){
if(a[i].checked){
alert(i+1);
}
}
}
面试官如果要问:你有什么要问的吗?(你就问他上面的方法怎么用闭包的方式去实现) |
请使用闭包的方式,写一段 JS 程序实现如下功能:函数每调用一次则该函数的返回值加 1 |
---|
- function creatSumFun(){
- var s=0;
- return function(){
- return ++s;
- }
- }
- var sumFun=creatSumFun();
- sumFun();
|
23、正则表达式(点击打开链接) |
---|
有字符串 var = 'abc345efgabcab',请写出 3 条 JS 语句分别实现如下 3 个功能: 1)去掉字符串中的a、b、c 字符,形成结果:'345efg' 2)将字符串中的数字用中括号括起来,形成结果:'abc3[5]efgabcab' 3)将字符串中的每个数字的值分别乘以 2,形成结果:'abc6810efgabcab'
- // 1)
- str.replace(/([a-c])/g, '');
- // 2)
- str.replace(/(\d)/g, '[$1]');
- // 3)
- str.replace(/(\d)/g, function(num) {return num*2;});
-
请写出一下正则表达式: 1)匹配一个全部是数字的字符串 2)提取一个 url 所使用的协议类型如 http、ftp 和 host 名称 |
- var patt1= /^\d+$/
- var patt2 = /^(\w+):\/\/w*\.?(\w+)\.\w+\/.*\.(\w+)/;
|
|
24、事件绑定和普通事件的区别 |
---|
普通添加事件的方法: var btn = document.getElementById("hello");
btn.onclick = function(){
alert(1);
}
btn.onclick = function(){
alert(2);
}
执行上面的代码只会alert 2 事件绑定方式添加事件: var btn = document.getElementById("hello");
btn.addEventListener("click",function(){
alert(1);
},false);
btn.addEventListener("click",function(){
alert(2);
},false);
执行上面的代码会先alert 1 再 alert 2 普通添加事件的方法不支持添加多个事件,最下面的事件会覆盖上面的,而事件绑定(addEventListener)方式添加事件可以添加多个。 |
25、请写出一个简单的单例 |
---|
- var singleTon = {
- m1: "memeber first ",
- m2: "memeber second ",
- f1: function ()
- {
- console.log("fun1 ");
- }
- };
其实就是字面量创建(做一个唯一判断,只能被实例化一个) <button type="button" id="btn">按钮</button> var createDiv=(function (){
var div1;
return function(){
if(!div1){
div1=document.createElement("div");
div1.innerHTML="我是一个div";
div1.style.display="none";;
document.body.appendChild(div1);
}
return div1;
}
})();
document.getElementById("btn").onclick=function(){
//点击后先产生一个div元素
var win=createDiv();
win.style.display="block";
} |
26、常见浏览器兼容性问题与解决方案(点击打开链接) |
---|
所谓的浏览器兼容性问题,是指因为不同的浏览器对同一段代码有不同的解析,造成页面显示效果不统一的情况。 在大多数情况下,我们的需求是,无论用户用什么浏览器来查看我们的网站或者登陆我们的系统,都应该是统一的显示效果。 所以浏览器的兼容性问题是前端开发人员经常会碰到和必须要解决的问题。 浏览器兼容问题一:不同浏览器的标签默认的外补丁和内补丁不同 问题症状:随便写几个标签,不加样式控制的情况下,各自的margin 和padding差异较大。 解决方案:CSS里 *{margin:0;padding:0;} 备注:这个是最常见的也是最易解决的一个浏览器兼容性问题,几乎所有的CSS文件开头都会用通配符*来设置各个标签的内外补丁是0。 浏览器兼容问题二:块属性标签float后,又有横行的margin情况下,在IE6显示margin比设置的大 问题症状:常见症状是IE6中后面的一块被顶到下一行 解决方案:在float的标签样式控制中加入 display:inline;将其转化为行内属性 备注:我们最常用的就是div+CSS布局了,而div就是一个典型的块属性标签,横向布局的时候我们通常都是用div float实现的,横向的间距设置如果用margin实现,这就是一个必然会碰到的兼容性问题。 浏览器兼容问题三:设置较小高度标签(一般小于10px),在IE6,IE7,遨游中高度超出自己设置高度 问题症状:IE6、7和遨游里这个标签的高度不受控制,超出自己设置的高度 解决方案:给超出高度的标签设置overflow:hidden;或者设置行高line-height 小于你设置的高度。 备注:这种情况一般出现在我们设置小圆角背景的标签里。出现这个问题的原因是IE8之前的浏览器都会给标签一个最小默认的行高的高度。即使你的标签是空的,这个标签的高度还是会达到默认的行高。 |
27、列举你用过的设计模式及其场景 |
---|
单例模式 | 策略模式 | 代理模式 | 迭代器模式 | 发布-订阅模式 | 命令模式 | 组合模式 | 模板方法模式 | 享元模式 | 职责链模式 | 中介者模式 | 装饰者模 | 状态模式 | 适配模式 |
28、移动端有哪些原生触摸事件? |
---|
touch类: touchstart, touchmove, touchend, touchcanceltap类: tap, longTap, singleTap, doubleTapswipe类: swipe, swipeLeft, swipeRight, swipeUp, swipeDown |
29、写出一个函数,实现对,对象的深拷贝(在原型和原型链的文章有介绍) |
---|
function deepCopy(p, c) { var c = c || {}; for (var i in p) { if (typeof p[i] === 'object') { c[i] = (p[i].constructor === Array) ? [] : {}; deepCopy(p[i], c[i]); } else { c[i] = p[i]; } } return c; } var Doctor = deepCopy(Chinese); Chinese.birthPlaces = ['北京','上海','香港']; Doctor.birthPlaces.push('厦门'); jQuery库使用的就是这种继承方法。 alert(Doctor.birthPlaces); //北京, 上海, 香港, 厦门 alert(Chinese.birthPlaces); //北京, 上海, 香港 |
30、写出一个函数,实现对,对象的浅拷贝 |
---|
var Chinese = { nation:'中国' }; var Doctor ={ career:'医生' } 这两个对象都是普通对象,不是构造函数,无法使用构造函数方法实现"继承"。 除了使用"prototype链"以外,还有另一种思路:把父对象的属性,全部拷贝给子对象,也能实现继承。 function extendCopy(p) { var c = {}; for (var i in p) { c[i] = p[i]; } c.uber = p; return c; } var Doctor = extendCopy(Chinese); Doctor.career = '医生'; alert(Doctor.nation); // 中国
这样的拷贝有一个问题。那就是,如果父对象的属性等于数组或另一个对象,那么实际上,子对象获得的只是一个内存地址,而不是真正拷贝,因此存在父对象被篡改的可能。 | 现在给Chinese添加一个"出生地"属性,它的值是一个数组 Chinese.birthPlaces = ['北京','上海','香港']; 通过extendCopy()函数,Doctor继承了Chinese。 var Doctor = extendCopy(Chinese); 我们为Doctor的"出生地"添加一个城市: Doctor.birthPlaces.push('厦门'); Chinese的"出生地"也被改掉了! alert(Doctor.birthPlaces); //北京, 上海, 香港, 厦门 alert(Chinese.birthPlaces); //北京, 上海, 香港, 厦门 extendCopy()只是拷贝基本类型的数据,我们把这种拷贝叫做"浅拷贝"。这是早期jQuery实现继承的方式。 |
31、写一段程序,实现在body里动态添加一个div标签节点 |
---|
<button type="button" id="btn">按钮</button> var createDiv=(function (){
var div1=document.createElement("div");
div1.innerHTML="我是一个div";
div1.style.display="none";;
document.body.appendChild(div1);
return div1;
});
document.getElementById("btn").onclick=function(){
//点击后先产生一个div元素
var win=createDiv();
win.style.display="block";
} |
32、请写出一个函数,入参是"a+b+c+d",出参是"abcd"字符串或者字符数组,类似于Array['a','b','c','d']; |
---|
aStr() var str='a+b+c+d'; function aStr(){ return console.log(str.split("+")); } |
33、介绍一下position,并写出他们的不同点 |
---|
绝对定位,相对定位,默认定位,固定定位 绝对定位 position: absolute; 1定位的块,脱离文档流不会独自占满一行 2不存在浮动一说 3如果父类有定位他是相对于父类的相对定位(只要是父类有定位,他都是相对于父类的定位) 如果父类没有定位,他就是相对于body 相对定位 position: relative; 1没有脱离文档流 2浮动是有效果的 3不管父类有没有定位,都是相对于父类的定位 固定定位 1脱离文档流 2不会出现滚动条 默认定位(静态定位)position: static; 存在自己的文档流中 数值越大层级越大 z-index: 2; overflow: hidden;多余的部分隐藏 overflow: auto;当内容大于盒子高度的时候产生滚动条 overflow: scroll;始终都有滚动条 |
34、http状态码,并作解释说明 |
---|
200:请求已成功,请求所希望的响应头或数据体将随此响应返回。 404:请求失败,请求所希望得到的资源未被在服务器上发现。没有信息能够告诉用户这个状况到底是暂时的还是永久的。假如服务器知道情况的话,应当使用410状态码来告知旧资源因为某些内部的配置机制问题,已经永久的不可用,而且没有任何可以跳转的地址。404这个状态码被广泛应用于当服务器不想揭示到底为何请求被拒绝或者没有其他适合的响应可用的情况下。 408:请求超时。客户端没有在服务器预备等待的时间内完成一个请求的发送。客户端可以随时再次提交这一请求而无需进行任何更改。 500:服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。一般来说,这个问题都会在服务器的程序码出错时出现。 |
35、web安全要考虑的危险因素【2个就差不多了(点击打开链接)】 |
---|
易受到SQL注入攻击 易受到跨站点脚本攻击 泄露敏感信息 |
36、var aArray=[1,[2,3],[2,[2,3,4,5]],[6,7],8],多维数组转换一维数组 [1, 2, 3, 4, 5, 6, 7, 8] ; |
---|
var aArray=[1,[2,3],[2,[2,3,4,5]],[6,7],8];
var new_Array=[];
function isArray(aArray) {//判断是否为数组
return aArray && ( typeof aArray === 'object') && (aArray.constructor == Array);
}
function recursion(aArray) {//递归
if (isArray(aArray)) {
for (var j = 0; j < aArray.length; j++) {
if (!isArray(aArray[j])) {//如果不是数组,则往下执行
new_Array.push(aArray[j]);
continue;
}
recursion(aArray[j]);//是数组的话,继续调用该方法
}
}
}
var newArr = [];
function getArrNElementNum(aArray) {
recursion(aArray);
for(var i=0, len=new_Array.length; i<len; i++){//去重
if(new_Array.indexOf(new_Array[i]) == i){
newArr.push(new_Array[i]);
}
}
newArr.sort(function(x,y){//升序排列
return x-y;
})
return newArr;
}
console.log(getArrNElementNum(aArray));
|
var arr=[1,[2,3],[2,[2,3,4,5]],[6,7],8];
var new_Array=[];
function recursion(arr) {//递归
if (arr instanceof Array) {
for (var j = 0; j < arr.length; j++) {
if (arr[j] instanceof Array) {//如果是数组,继续调用该方法
recursion(arr[j])
}else{
new_Array.push(arr[j]);//不是的话,插入新的数组
}
}
}
return new_Array;
}
var newArr=recursion(aArray);
newArr=Array.from(new Set(newArr));//去重
newArr.sort(function(x,y){//从大到小排序
return y-x;
})
console.log(newArr);//输出[]
37、ES6 十个新特性(点击打开链接)(阮一峰大神的ES6介绍) |
---|
- 默认参数
- 模版表达式
- 多行字符串
- 拆包表达式
- 改进的对象表达式
- 箭头函数
=&> - Promise
- 块级作用域的
let 和const - 类
- 模块化
|
38 变量提升 (变量和function都会提前声明,但是function会覆盖变量(在不赋值的前提下) ) |
---|
1、function fn(a){
console.log(a);
var a = 2;
function a(){};
console.log(a);
}
fn(1);
//ƒ a(){}
//2 2、var b = 10;
(function b() {
b = 20;
console.log(b);
})();
// ƒ b() {
// b = 20;
// console.log(b);
//} 3、 var a = 18;
f1();
function f1(){
var a;
var b=9;
console.log(a);
console.log(b);
var a = '123';
}
//undefied 9 解释: 1、function fn(a){
window.a();//优先级高,调用下面的a 的函数()
var a;
console.log(a);
var a = 2;
function a(){};
console.log(a);
}
fn(1); 2、var b = 10;
window.b()
(function b() {
b = 20;
console.log(b);
})(); 3、var a = 18;
f1();
function f1(){
var b=9;
var a;
console.log(a);
console.log(b);
var a = '123';
}
//undefied 9 |
39、var str='aaaabbccccddeffgh'获取str里出现次数最多的字母 |
---|
var str='aaaabbccccddeffgh';
var json1={};
for(var i=0;i<str.length;i++){
if(json1[str[i]]){
json1[str[i]]++;
}else{
json1[str[i]]=1;
}
}
var n=0;
var s='';
for(var name in json1){
if(n<json1[name]){
n=json1[name];
s=name;
}
}
console.log(s+'出现了'+n+'次'); |
40、邮箱正则表达式验证 |
---|
^[A-Za-z\d]+([-_.][A-Za-z\d]+)*@([A-Za-z\d]+[-.])+[A-Za-z\d]{2,4}$ |
41、jQuery的事件委托方法on、live、delegate之间有什么区别? |
---|
live 把事件委托交给了document(根节点),document 向下去寻找符合条件的元素(), 不用等待document加载结束也可以生效。 delegate可指定事件委托对象,相比于live性能更优,直接锁定指定选择器; on事件委托对象选填,如果不填,即给对象自身注册事件,填了作用和delegate一致。 band只能给调用它的时候已经存在的元素绑定事件,不能给未来新增的元素绑定事件,存在局限性。 |
|
|
|
|