前端常见面试题

半腔热情 提交于 2020-04-01 07:36:36

一.JS

(1) 在函数中赋值,多次赋值,出现问题

var a = b = c = 10;
console.log(delete a); //false
console.log(delete b); //true
console.log(delete c); //true

 

function fn(){
    var a = b = c = 10;
}
fn();

console.log(b); //10
console.log(c); //10
console.log(a); //a is not defined

 

(2)数组的length 赋值给变量后,无法判断数组长度

var arr = [1,2,3],
    i = 0,
    len = arr.length;
arr.length = 2;
console.log(len); //3
console.log(arr.length);  //2

 

(3) 截取字符

console.log('abcdefg'.substring(4))  // efg

 

(4) 统计一个字符里出现最多的字母和出现次数

var str = 'asdfssaaasasasasaa';
var json = {};

for (var i = 0; i < str.length; i++) {
        if(!json[str.charAt(i)]){
                json[str.charAt(i)] = 1;
        }else{
                json[str.charAt(i)]++;
        }
};
var iMax = 0;
var iIndex = '';
for(var i in json){
        if(json[i]>iMax){
                iMax = json[i];
                iIndex = i;
        }
}
alert('出现次数最多的是:'+iIndex+'出现'+iMax+'次');

 

(5)判断变量是不是字符

var obj = 'sss'
typeof(obj) == 'string'
obj.constructor == String; // true

 

(6)你如何组织自己的代码?是使用模块模式,还是使用经典继承的方法?

对内:模块模式
对外:继承

 

(7) 你如何优化自己的代码?

代码重用
避免全局变量(命名空间,封闭空间,模块化mvc..)
拆分函数避免函数过于臃肿

 

(8)你能解释一下JavaScript中的继承是如何工作的吗?

子构造函数中执行父构造函数,并用call\apply改变this
克隆父构造函数原型上的方法

 

(9)行内元素有哪些?块级元素有哪些?CSS的盒模型?

块级元素:div p h1 h2 h3 h4 form ul
行内元素: a b br i span input select
Css盒模型:content,border ,margin,padding

 

(10) Doctype? 严格模式与混杂模式-如何触发这两种模式,区分它们有何意义?

用于声明文档使用那种规范(html/Xhtml)一般为 严格 过度 基于框架的html文档
加入XMl声明可触发,解析方式更改为IE5.5 拥有IE5.5的bug

 

(11) CSS引入的方式有哪些? link和@import的区别是?

内联 内嵌 外链 导入
区别 :同时加载
前者无兼容性,后者CSS2.1以下浏览器不支持
Link 支持使用javascript改变样式,后者不可

 

(12) CSS选择符有哪些?哪些属性可以继承?优先级算法如何计算?内联和important哪个优先级高?

标签选择符 类选择符 id选择符
Id>class>标签选择
important优先级高

1、基本选择器:直接根据id、css类名、元素名返回匹配的dom元素。

2、层次选择器:也叫做路径选择器,可以根据路径层次来选择相应的DOM元素。

3、过滤选择器:在前面的基础上过滤相关条件,得到匹配的dom元素。

 

 

(13) 前端页面有哪三层构成,分别是什么?作用是什么?

结构层 Html 表示层 CSS 行为层 js

 

(14) 你做的页面在哪些流览器测试过?这些浏览器的内核分别是什么?

Ie(Ie内核) 火狐(Gecko) 谷歌(webkit) opear(Presto)

 

(15)写出几种IE6 BUG的解决方法

1.双边距 : BUG float引起的 使用display
2.3像素问题 : 使用float引起的 使用dislpay:inline -3px
3.超链接hover 点击后失效 : 使用正确的书写顺序 link visited hover active
4.Ie z-index问题 : 给父级添加position:relative
5.select 在ie6下遮盖 使用iframe嵌套
6.为什么没有办法定义1px左右的宽度容器(IE6默认的行高造成的,使用over:hidden,zoom:0.08 line-height:1px)

 

(16)标签上title与alt属性的区别是什么?

Alt 当图片不显示是 用文字代表。
Title 为该属性提供信息

 

(17) 你如何对网站的文件和资源进行优化?期待的解决方案包括:

文件合并
文件最小化/文件压缩
使用CDN托管
缓存的使用

 

(18) 什么是语义化的HTML?

直观的认识标签 对于搜索引擎的抓取有好处

 

(19)数组方法pop() push() unshift() shift()

Push()尾部添加 pop()尾部删除
Unshift()头部添加 shift()头部删除

 

(20) ajax请求的时候get 和post方式的区别

一个在url后面 一个放在虚拟载体里面
有大小限制
安全问题
应用不同 一个是论坛等只需要请求的,一个是类似修改密码的

 

(21) call和apply的区别

Object.call(this,obj1,obj2,obj3)
Object.apply(this,arguments)

 

(22)事件委托是什么

让利用事件冒泡的原理,让自己的所触发的事件,让他的父元素代替执行!

 

(23)闭包是什么,有什么特性,对页面有什么影响

闭包就是能够读取其他函数内部变量的函数。

 

(24) 添加 删除 替换 插入到某个接点的方法

obj.appendChild()
obj.innersetBefore
obj.replaceChild
obj.removeChild

 

(25)解释ajax

Ajax是页面无刷新请求数据操作

 

(26)document load 和document ready的区别

Document.ready原生种没有这个方法,jquery中有 $().ready(function)

1、我们可以在页面中使用多个document.ready(),但只能使用一次onload()。

2、document.ready()函数在页面DOM元素加载完以后就会被调用,而onload()函数则要在所有的关联资源(包括图像、音频)加载完毕后才会调用。

 

(27)”==”和“===”的不同

前者会自动转换类型
后者不会

 

(28)jQuery中的Delegate()函数有什么作用?

$("ul").delegate("li", "click", function(){

$(this).hide();

});

 

(29)怎样用jQuery编码和解码URL?

encodeURIComponent(url)
decodeURIComponent(url)

 

(30) 闭包,输出是true还是false

(function() {     
   if (g() && [] == ![]) {     
//应该看成if((g() && [] )== ![])   
//因为g()是false后面那个&&[]就没起作用 整个都是false    
//![]也是false 所以if成立 进入if块内   
      f = function f() {return false;};     
//重新定义f    
      function g() {return true;}     
//这句没用   
   }     
})();    
alert(f());   
//false  

 

(31)获取今日日期

function DateDemo(){ 
var d, s="今天日期是:"; 
d = new Date(); 
s += d.getMonth() + "/"; 
s += d.getDate() + "/"; 
s += d.getYear(); 
return s; 
} 

DateDemo()

 

(32)ajax

var request = new XMLHttpRequest()

if(window.XMLHttpRequest){
    request = new XMLHttpRequest()
}else{
    request = new ActiveXObject("Microsoft.XMLHTTP")
}

request.open('POST','create.php',true)
request.setRequestHeader('Content-type','application/x-www-from-urlencoded')
request.send('name=王二狗&sex=女')

request.onreadystatechange = function(){
    if(request.readyState === 4 && request.status ===200){
        // do sth
    }
}

 

(33)添加事件监听

document.addEventListener("click",function(){
    console.log("添加事件监听")
})

 

(34)数组

// “最后加” concat 连接两个或更多的数组,并返回结果。
    var a = ['a','b','c'];
    var b = ['x','y','z'];
    var c = a.concat(b,true);
    // alert(c)  //c变成 a,b,c,x,y,z


// join 把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔。
    var d = a.join('');
    // alert(d)  //d变成abc
    var e = a.join(';');
    // alert(e)  //d变成a;b;c


// “最后加” push 向数组的末尾添加一个或更多元素,并返回新的长度。
    a.push('d');
    // alert(a) //a数组变成a,b,c,d


// reverse 颠倒数组中元素的顺序。
    a.reverse()
    // alert(a)  //a数组变成d,c,b,a


// “最后删1个” pop 删除并返回数组的最后一个元素
    a.pop('') 
    // alert(a)  //a数组变成d,c,b


// “开始删1个” shift 删除并返回数组的第一个元素
    a.shift();
    // alert(a)  //a数组变成c,b


// “开始增加n个” unshift 向数组的开头添加一个或更多元素,并返回新的长度。
    var h = ['a','b','c','d'];
    h.unshift('?','@')
    alert(h)


// "复制一段元素" slice(start,end) 从某个已有的数组返回选定的元素
    var f = a.slice(1,2)
    // alert(f) //复制了b元素


// sort 对数组的元素进行排序
    var e = ['f','e','d','i','a','p','c']
    var f = ['1','3','6','5','4']
    // e.sort();  //字母排序 a,c,d,e,f,i,p
    // alert(e) 
    f.sort();  //数字排序 1,3,4,5,6
    // alert(f) 



// “替换一段” splice(start,deleteCount,item...)删除元素,并向数组添加新元素。
    var g = ['a','b','c']
    g.splice(0,1,'ache','bug'); //数组0-1的位置上被替换成ache和bug
    // alert(g)

 

(35)异步加载

// 异步加载js
(function(){
    var _asyn_js_data = ['index.js','index1.js','index2.js','index3.js']
    for(var i=0;i<_asyn_js_data.length;i++){
        var script=document.createElement("script"); 
        script.setAttribute("src", _asyn_js_data[i]); 
        var heads = document.getElementsByTagName("head");
        if(heads.length){
            heads[0].appendChild(script);
        }else{
            document.documentElement.appendChild(script); 
        }           
    }
})();


// 异步加载图片
(function(){
    var _img_src = ['img/img1.png','img/img2.png','img/img3.png']
    var _img = document.getElementsByTagName("img")
    for(var i=0;i<_img.length;i++){
        _img[i].setAttribute("src",_img_src[i]); 
    }
})();

 

(36)回调函数

function writeCode(callback){
    console.log("i am waiting....")
    callback();
    console.log("i am ready")
}
function prepare(){
    console.log("i am preparing...")
}

writeCode(prepare)

 

(37)小知识

// 可视宽高
var ch = document.documentElement.clientHeight
var cw = document.documentElement.clientWidth

// 内容高度
var sh = document.documentElement.scrollHeight

// 游览器滚动高度
var st = document.body.scrollTop




// 提交之后,立刻禁用点击按钮
document.getElementById("btn").disabled = true;
// 设置某<input>控件为只读
document.getElementById("btn").readOnly = true;



// 十进制转化为一个十六进制值
var num = 255;
console.log(num.toString(16));//ff
// 整型转换
parseInt("12.2222")




// 随机产生颜色
 function randomVal(val){
    return Math.floor(Math.random()*(val + 1));
}
function randomColor(){
    return 'rgb(' + randomVal(255) + ',' + randomVal(255) + ',' + randomVal(255) + ')';
}


// 在角度和弧度之间转换
var rad = degrees*(Math.PI/180);
var degrees = rad*(180/Math.PI);


// 排序数组
var fruits = ['banana','apple','orange','strawberry'];
console.log(fruits.sort());//Array [ "apple", "banana", "orange", "strawberry" ]
var num = [32,43,2,5,-23,0,4];
console.log(num.sort());//Array [ -23, 0, 2, 32, 4, 43, 5 ]

 

(38)小数点

// toExponential 保留小数点( 0-20 bit )
    document.writeln(Math.PI.toExponential(0)); //3e+0 
    document.writeln(Math.PI.toExponential(2)); //3.14e+0
    document.writeln(Math.PI.toExponential(4)); //3.1416e+0
    document.writeln(Math.PI.toExponential(7)); //3.1415927e+0

// toFixed 换成十进制后 保留小数点( 0-20 bit ) 
    document.writeln(Math.PI.toFixed(0)); 
    document.writeln(Math.PI.toFixed(2)); 
    document.writeln(Math.PI.toFixed(4)); 
    document.writeln(Math.PI.toFixed(7)); //3.1415927

// toPrecision 换成十进制后 保留小数点( 1-21 bit ) 
    document.writeln(Math.PI.toPrecision(1)); //3 
    document.writeln(Math.PI.toPrecision(2)); //3.1 
    document.writeln(Math.PI.toPrecision(4)); //3.142 
    document.writeln(Math.PI.toPrecision(7)); //3.141593

// toString(radix) radix是基数 默认为10 换成十进制后 保留小数点( 2-36 bit ) 
    document.writeln(Math.PI.toString(2)); //11.001001000011111101101010100010001000010110100011
    document.writeln(Math.PI.toString(8)); //3.1103755242102643
    document.writeln(Math.PI.toString(16)); //3.243f6a8885a3 
    document.writeln(Math.PI.toString()); //3.141592653589793

 

(39)即时函数

(function(){
    var days = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']
    var today = new Date()
    var msg = "Today is" + days[today.getDay()] + ',' + today.getDate()
    console.log(msg)
})();   // Today isThu,29


// 即时函数的参数
(function(who,when){
    console.log(' i met ' + who + ' on ' + when)
})("cynthia",new Date());  //i met cynthai on Thu Oct 29 2015 18:03:09 GMT+0800 (中国标准时间)

 

(40)组合继承

// 组合继承
// 其基本思路是使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承

function Person(name){
  this.name = name;
  this.friends = ["Jack","John","Kim"];
}
Person.prototype.getName = function(){
  console.log(this.name);
}
function SuperPerson(name,sex){
 //继承Person
 Person.call(this,name);/*第二次调用父类型的构造函数,在实例上又创建了一次属性name和frieds,屏蔽第一次调用时创建的*/
 //实例属性
 this.sex = sex;
}
SuperPerson.prototype = new Person();//重写原型,第一次调用父类型的构造函数
SuperPerson.prototype.constructor = SuperPerson;
//添加新方法
SuperPerson.prototype.getSex = function(){
console.log(this.sex);
};
var Tom = new SuperPerson("Tom","man");
Tom.friends.push("Amy");
console.log(Tom.friends);// ["Jack", "John", "Kim", "Amy"]
Tom.getName();// Tom 
Tom.getSex();// man

var David = new SuperPerson("David","man");
console.log(David.friends);// ["Jack", "John", "Kim"]
David.getName();// David
David.getSex();// man 

 

(41)寄生继承

// 寄生式继承
// 其基本思路是类似创建对象时的工厂模式,将继承过程封装在一个函数里,然后返回一个对象

function createObject(o){
  var clone = Object.create(o);
  clone.sayHi = function(){
   console.log("Hi~");
  };
 return clone;
}
var person = {
  name: "Tom",
  friends:  ["Jack", "John", "Kim"]
};
var David = createObject(person);
David.sayHi();//Hi~

 

(42)原型式继承

// 原型式继承
// 其基本思路是借助原型可以基于已有的对象创建新的对象

function object(o){
 function F(){}
 F.prototype = o;
 return new F();
}

var person = {
  name: "Tom",
  friends:  ["Jack", "John", "Kim"]
};
var David = object(person);
David.name = "David";
David.friends.push("Amy");
console.log(David.friends);// ["Jack", "John", "Kim", "Amy"]
var Rob = object(person);
Rob.name = "Rob";
console.log(Rob.friends);// ["Jack", "John", "Kim", "Amy"]

 

(43)原型链

// 原型链
// 其基本思路是利用原型让一个引用类型继承另一个引用类型的属性和方法

function Person(){
    this.name = "Person";
}
Person.prototype.getName = function(){
    return this.name;
}
function SuperPerson(name,sex){
    this.name = name;
    this.sex = sex;
}
SuperPerson.prototype = new Person();//重写原型

//在添加新方法或重写原型中的方法时,一定要在重写原型的语句后面,而且不能使用字面量添加新方法,不然又会再一次重写原型,原型链被切断

SuperPerson.prototype.getSex = function(){
    return this.sex;
}

var Tom = new SuperPerson("Tom","man");
console.log(Tom.getName())
console.log(Tom.getSex())

 

(44)任意参数的加法运算

function add(){
           var sum = 0
           for(var i=0;i<arguments.length;i++){
               if(!isNaN(arguments[i])){
                 sum += parseFloat(arguments[i])
               }
           }
           return sum
        }
        console.log(add(1,2))
        console.log(add(1,2,3,4,5,6))

 

(45)闭包

var name = "cynthia"
        var obj = {
            name : "wuqian",
            sex : "girl",
            getName : function(){
                 return this.name
            } 
        }
        console.log(obj.getName()) //wuqian
        console.log(name)  //cynthia

 

(46)字面量

var cyn = {
            name : "wuqian",
            sex : "girl",
            Add : function(){
                var sum = 0
                for(var i=0;i<arguments.length;i++){
                   if(!isNaN(arguments[i])){
                     sum += parseFloat(arguments[i])        
                   }
                }
                return sum
            }  
        };
        cyn.say = function(){
            return "给对象字面量添加方法"
        }
        cyn.socre = "给对象字面量添加变量"

        console.log(cyn.Add(100,300))  //400
        console.log(cyn.say())  //给对象字面量添加方法
        console.log(cyn.socre)  //给对象字面量添加变量

 

(47)常用正则

//手机号验证
var regMobile=/^1[3,5,8]\d{9}$/;
 
//固定电话
var regPhone=/^(^0\d{2}-?\d{8}$)|(^0\d{3}-?\d{7}$)|(^\(0\d{2}\)-?\d{8}$)|(^\(0\d{3}\)-?\d{7}$)$/;
 
/*
 * 用户名
 * 只能是字母数字下划线,并且以字母开头(5-16位)
 */
var regUserName=/^[a-zA-Z]\w{4,15}$/;
 
 
 
//QQ
var regQQ=/^[1-9]*[1-9][0-9]*$/;
 
//email
var regEmail=/^(\w-*\.*)+@(\w-?)+(\.\w{2,})+$/;
 
//身份证号
var regIDcard=/^\d{15}$)|(^\d{17}([0-9]|X)$/;

 

(48)定时输出

var cyn = function(){
    console.log("我是定时输出的函数")
}
setInterval(cyn,1000)

 

(49)延时输出

var cyn = function(){
    console.log("我是延时输出的函数")
}
setTimeout(cyn,5000)

 

(50)字符的处理

// string.charAt(pos) 返回string中pos所在位置的字符
    var name = "Cynthia";
    var i = name.charAt(0)
    // alert(i)  //C

// string.charCodeAt(pos) 返回string中pos所在位置的字符的字符码位
    var n = name.charCodeAt(0)
    // alert(n)  //67

// string.concat(string)
    var s = 'C'.concat('i','n','c','o')
    // alert(s)   // Cinco

// string.indexOf(searchString,position) "从头到尾"在string中查找searchString字符,找到了,返回字符的位置;
// 否则,返回-1;position可以设置开始查找的位置
    var text = 'hello my name is wuqian'
    var p = text.indexOf('my');  //6
    var p = text.indexOf('my',13)   //-1
    // alert(p)


// string.lastIndexOf(searchString,position) "从尾到头"在string中查找searchString字符,找到了,返回字符的位置;
// 否则,返回-1;position可以设置开始查找的位置 
    var text2 = 'hello my name is wuqian'
    var p2 = text2.lastIndexOf('my');  //6
    // var p2 = text2.lastIndexOf('s')   //15
    // alert(p2)


// string.match(regexp) 根据regexp正则要求对string进行匹配
    // var text3 = '<html><body><p>'+'this is <b>bold</b><\/p><\/body><\/html>'
    // var tags = /[^<>]+|<(\/?)([A-Za-z]+)(^<>*)>/g;
    // var a,i;
    // a = text3.match(tags);
    // for(i=0;i<a.length;i+=1){
    //     document.writeln(('// [' + i + ']' + a[i]).entityify());
    // }


//string.localeCompare(that)  比较
    var m = ['AAA','A','aa','a','Aa','aaa']
    m.sort(function(a,b){
        return a.localeCompare(b)
    })
    // alert(m)  // a,A,aa,AA,aaa,AAA


// string.replace(searchValue,replaceValue) searchValue如果是一个字符,那么只会替换第一处
// searchValue如果是一个正则表达式
    var result = 'mother_in_law'.replace('_','-') 
    // alert(result) //mother-in_law


// string.slice(start,end) 复制start到end之间的string
    var q  = 'hello world ! an message from wuqian'
    var qm = q.slice(6,11)
    // alert(qm)  // world
   
// string.split(separator,limit)
    var digits = '0123456789'
    var a = digits.split('',5)
    alert(a)

//string.substring(start,end)  和slice一样,不能处理负数

//string.toLocaleLowerCase()

//string.toLocaleUpperCase()

//string.toLowerCase()

//string.toUpperCase()

 

(51)找一组数当中最大的数

// 一般这样做
            var number = [12,111,256,1,5,687,255,103]
        var max = 0 ;
        for(var i =0 ; i < number.length ;i++){
            if(number[i] > max){
                max = number[i]
            }
        }
        alert(max)
// 原生方法更简单 如下
        var number = [12,111,256,1,5,687,255,103]
        number.sort(function(a,b){return b - a})
        alert(number[0])

// 更加简介的方法 如下
        var a = Math.max(12,111,256,1,5,687,255,103)
        alert(a)

 

(52)对象构造器

function Name(firstName,lastName){
    this.firstName = firstName ;
    this.lastName = lastName ;
}

var cynthia = new Name("wu","qian")

 

(53)自调用函数

(function(){
    // ...
})

(function(a,b){
    var result = a + b
    return result
}(10,20))

 

(54)从数组中随机获取成员

var items = [5,12,35,458,14,28,62,43,57,4,9,1,56]
var randomItem = items[Math.random()*length]
console.log(randomItem)

 

(55)获取指定范围的随机数

var max = 250
var min = 1
var x = Math.floor(Math.random()*(max-min+1))-min
console.log(x)

 

(56)生成从0到指定值的数字数组

var numArray = []
var max = 101
for(var i=1;i<=max;i++){
    numArray.push(i)
}
console.log(numArray)//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100…]

 

(57)生成从0到指定值的数字中奇数的数组

var numArray = []
var max = 101
for(var i=1;i<=max;i++){
    numArray.push(i++)
}
console.log(numArray)//[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99, 101]

 

(58) 获取数组中的最大值和最小值

var num = [5,6,8,2,74,66,1587,2664,3,5,8,4,26598,898]
var max = Math.max.apply(Math,num)
var min = Math.min.apply(Math,num)
console.log(max)
console.log(min)

 

(59)清空数组

var myArray = [12 , 222 , 1000 ]; 
myArray.length = 0; 
console.log(myArray)

 

(60)写一个switch/case例子

function Grade(grade){
    switch (grade){
        case 60:
            console.log("及格")
            break;
        case 70:
            console.log("良")
            break;
        case 90:
            console.log("优")
            break;
        default:
            console.log("exit")
            break
    }
}

Grade(70)

// case后面不能接判断 必须是常量

 

(61)javascript数组迭代与归并

// every() 对数组中的每一项运行给定函数,如果每一项都返回true,则返回true   
// filter() 对数组中的每一项运行给定函数,哪一项返回了true,则添加到数组中,返回数组
// forEach() 对数组中的每一项运行给定函数,没有返回值
// map() 对数组中的每一项运行给定函数,返回每次调用的结果,组成的数组
// some() 对数组中的每一项运行给定函数,如果数组任意一项返回true,则返回true

 

(62)说说jquery中添加 after before append prepend的区别

   after 是在选中元素的后面  before是在选中元素的前面

  append 是在选中元素的内部的所有元素后面 prepend是在选中元素的内部的所有元素的前面

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!