@(汇总)[js]
基础
Javascript是一种弱类型语言,它分别有什么优点和缺点
弱类型语言:简单好用,更灵活多变。但是会牺牲性能,比如一些隐含的类型转换
强类型语言:类型转换的时候非常严格,,强类型语言是直接操纵内存,容易出内存越界和泄漏的问题。在类型的转换方面是很多约束,甚至强制转换也要很谨慎,一不小心就出大问题。
Javascript里面的数据类型有哪些
5个简单数据类型(基本数据类型)+ 1个复杂数据类型
undefiend, number string null boolean + object
有几种方式可以判断数据类型
typeof和intanceof
其实typeof和instanceof的目的都是检测变量的类型,两个的区别在于typeof一般是检测的是基本数据类型,instanceof主要检测的是引用类型!
基本类型和引用类型有什么区别
赋值的时候基本类型按值,引用类型按引用,就是基本类型会复制一份,引用类型就是一个新的指针
函数传参的时候都是按值传递
{}=={}? []==[]? null==undefined?
{}=={}()
[]==[]()
null == undefined(对)
写个方法判断一个变量的类型
函数
函数声明和函数表达式有什么区别
函数声明会将那个函数提升到最前面,成为全局函数。函数声明要指定函数名,而函数表达式不用,可以用作匿名函数。
创建函数的方式:函数声明、函数表达式、还有一种不常见的方式就是Function构造器。
函数声明:
function add(a,b) {
a = +a;
b = +b;
if (isNaN(a) || isNaN(b)) {
return;
}
return a + b;
}
函数表达式的几种方式:
// 函数表达式
var add = function(a, b) {
// do sth
}
// 匿名函数定义的一个立即执行函数表达式
(function() {
// do sth
})();
// 作为返回值的函数表达式
return function() {
// do sth
};
// 命名式函数表达式
var add = function foo (a, b) {
// do sth
}
函数声明与函数表达式的主要区别就是:函数声明会被前置
函数声明前置:
// function add(a,b) 已经声明前置了,可以正常调用
var num = add(1, 2);
console.log(num); // 3
function add(a,b) {
a = +a;
b = +b;
if (isNaN(a) || isNaN(b)) {
return;
}
return a + b;
}
函数表达式前置:
// var add 变量声明提前,此时变量的值是undefined
var num = add(1, 2);
console.log(num); // TypeError:undefined is not a function
var add = function(a, b) {
a = +a;
b = +b;
if (isNaN(a) || isNaN(b)) {
return;
}
return a + b;
}
Function构造器:
var func = new Function('a', 'b', 'console.log(a+b);');
fun(1, 2); // 3
// 和上面的方式没有区别
var func = Function('a', 'b', 'console.log(a+b);');
func(1, 2); // 3
区别:
原型与原型链
每一个构造函数都有一个prototype,指向一个对象,这个对象的所有属性和方法,都会被构造函数的实例继承。
原型链作为实现继承的主要方法。其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。
在JavaScript中,用proto 属性来表示一个对象的原型链。当查找一个对象的属性时,JavaScript 会向上遍历原型链,直到找到给定名称的属性为止!
函数有哪几种调用方式
直接调用
作为对象的方法调用
apply,call
作用域
JS没有块作用域,只有函数作用域
作用域链的作用是保证执行环境里有权访问的变量和函数是有序的,作用域链的变量只能向上访问,变量访问到window对象即被终止,作用域链向下访问变量是不被允许的。
作用域链是什么
A://说的不是很清楚
闭包
闭包是什么
闭包是指有权访问另一个函数作用域中的变量的函数
创建闭包的方式:
在一个函数内部创建另一个函数
闭包的作用:
1.让这些函数的值始终保存在内存中
滥用闭包有什么副作用
由于闭包会携带包含它的函数的作用域链,因此会比其他函数占用更多的内存。过度使用闭包可能会导致内存占用过多,所以只在绝对必要时使用闭包。
闭包实现块级作用域
(function() {
})();
闭包的作用/应用
匿名自执行函数、缓存、实现封装(主要作用)、实现面向对象中的对象
1 匿名自执行函数
我们知道所有的变量,如果不加上var关键字,则默认的会添加到全局对象的属性上去,这样的临时变量加入全局对象有很多坏处,
比如:别的函数可能误用这些变量;造成全局对象过于庞大,影响访问速度(因为变量的取值是需要从原型链上遍历的)。
除了每次使用变量都是用var关键字外,我们在实际情况下经常遇到这样一种情况,即有的函数只需要执行一次,其内部变量无需维护,
比如UI的初始化,那么我们可以使用闭包:
var datamodel = {
table : [],
tree : {}
};
(function(dm){
for(var i = 0; i < dm.table.rows; i++){
var row = dm.table.rows[i];
for(var j = 0; j < row.cells; i++){
drawCell(i, j);
}
}
//build dm.tree
})(datamodel);
```
我们创建了一个匿名的函数,并立即执行它,由于外部无法引用它内部的变量,
因此在执行完后很快就会被释放,关键是这种机制不会污染全局对象。
**2缓存**
再来看一个例子,设想我们有一个处理过程很耗时的函数对象,每次调用都会花费很长时间,
那么我们就需要将计算出来的值存储起来,当调用这个函数的时候,首先在缓存中查找,如果找不到,则进行计算,
然后更新缓存并返回值,如果找到了,直接返回查找到的值即可。闭包正是可以做到这一点,因为它不会释放外部的引用,
从而函数内部的值可以得以保留。
```
var CachedSearchBox = (function(){
var cache = {},
count = [];
return {
attachSearchBox : function(dsid){
if(dsid in cache){//如果结果在缓存中
return cache[dsid];//直接返回缓存中的对象
}
var fsb = new uikit.webctrl.SearchBox(dsid);//新建
cache[dsid] = fsb;//更新缓存
if(count.length > 100){//保正缓存的大小<=100
delete cache[count.shift()];
}
return fsb;
},
clearSearchBox : function(dsid){
if(dsid in cache){
cache[dsid].clearSelection();
}
}
};
})();
CachedSearchBox.attachSearchBox("input1");
```
这样,当我们第二次调用CachedSearchBox.attachSerachBox(“input1”)的时候,
我们就可以从缓存中取道该对象,而不用再去创建一个新的searchbox对象。
**3 实现封装**
可以先来看一个关于封装的例子,在person之外的地方无法访问其内部的变量,而通过提供闭包的形式来访问:
```
var person = function(){
//变量作用域为函数内部,外部无法访问
var name = "default";
return {
getName : function(){
return name;
},
setName : function(newName){
name = newName;
}
}
}();
print(person.name);//直接访问,结果为undefined
print(person.getName());
person.setName("abruzzi");
print(person.getName());
得到结果如下:
undefined
default
abruzzi
```
4 **实现面向对象中的对象**
传统的对象语言都提供类的模板机制,
这样不同的对象(类的实例)拥有独立的成员及状态,互不干涉。虽然JavaScript中没有类这样的机制,但是通过使用闭包,
我们可以模拟出这样的机制。还是以上边的例子来讲:
```
function Person(){
var name = "default";
return {
getName : function(){
return name;
},
setName : function(newName){
name = newName;
}
}
};
var john = Person();
print(john.getName());
john.setName("john");
print(john.getName());
var jack = Person();
print(jack.getName());
jack.setName("jack");
print(jack.getName());
运行结果如下:
default
john
default
jack
```
由此代码可知,john和jack都可以称为是Person这个类的实例,因为这两个实例对name这个成员的访问是独立的,互不影响的。
####实现一个暴露内部变量,而且外部可以访问修改的函数
(get和set,闭包实现)
```
var person = function(){
//变量作用域为函数内部,外部无法访问
var name = "default";
return {
getName : function(){
return name;
},
setName : function(newName){
name = newName;
}
}
}();
print(person.name);//直接访问,结果为undefined
print(person.getName());
person.setName("abruzzi");
print(person.getName());
得到结果如下:
undefined
default
abruzzi
```
####从几个li中取下标的闭包代码
```
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
var li=document.getElementsByTagName("li");
for(var i=0;i<li.length;i++) {
(function(x) {
li[x].onclick=function(){alert(x);}
})(i);
}
```
####实现一个闭包的例子(实现了一个定时函数传值的)
```
闭包:
for(var i = 0; i < 10; i++ ){
(function(x){
setTimeout(function(){
console.log(x)
},x*1000)
})(i)
}
或者用全局变量实现
```
###面向对象
------------------------------------------
####js原型链的继承
####静态属性怎么继承
####js原型链以及特点
####面向对象有哪几个特点
封装,继承,多态
####对象的继承
####创建对象的几种方式
####继承的两种方法。
原型链继承和类继承。然后类继承只继承了实例属性,没有原型属性。
原型链继承可以继承所有。然后用apply和call怎么继承原型链上的共享属性?通过空函数传值。新建一个空函数C。C实例化后C的实例属性就是空,然后用B的apply/call去继承C,相当于继承了C的实例属性
####JS怎么实现继承
将父对象的一个实例赋值给子对象的原型
[js实现继承的5种方式](http://javapolo.iteye.com/blog/1996871)
####new操作符时具体是干了些什么
New:
1、创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
2、属性和方法被加入到 this 引用的对象中。
3、新创建的对象由 this 所引用,并且最后隐式的返回 this 。
####怎么判断属性来自对象自身还是原型链
hasOwnProperty
####一个对象的实例,如何统计被几次调用过,分别具体被哪些函数调用过,可以有哪些方法
####写个Animal类
有个Cat类继承它,要求新建一个Cat的实例,可以调用catch方法输出自己的名字“大白的猫”;
####实现私有变量
(这里当时还没看到相关部分,只能想到用属性的setter、getter来做。。。😂面试官各种启发呀。。);
####手写一个类的继承,并解释一下
####手写JS实现类继承,讲原型链原理
###数组
------------------------------------------
####Array对象自带的方法,一一列举
var arr = [0,1,2];
1.pop():删除数组的最后一个元素,减少数组的长度,返回删除的值。
这里是2.
2.push(3):将参数加载到数组的最后,返回新数组的长度。
现在arr中是:0,1,2,3
3.shift():删除数组的第一个元素,返回删除的值,同时数组长度减一。
这里是0
4.unshift(3,4):把参数加载数组的前面,返回新数组的长度。
现在arr:中是3,4,0,1,2
5.sort():按指定的参数对数组进行排序 ,返回的值是经过排序之后的数组
```
var a = [0,1,5,10,15];
var b = a.sort(); // a:[1,2,3,4,5] b:[0,1,10,15,5]
正确的排序:
function compare(val1, val2) {
return val1 - val2;
}
arr = [3,7,6];
arr.sort(compare); // 3,6,7
```
6.reverse():反转数组项的顺序,返回的值是经过排序之后的数组
7.concat(3,4):把两个数组拼接起来。 返回的值是一个副本
8.slice(start,end):返回从原数组中指定开始下标到结束下标之间的项组成的新数组
```
var colors = ["red", "green", "blue", "yellow", "purple"];
// 一个参数:[ ,+∞)
var color1 = colors.slice(1);
alert(color1); // green,blue,yellow,purple
// 两个参数:[,)
var color2 = colors.slice(1,4);
alert(color2); // green,blue,yellow
```
6splice():
删除: 2个参数,起始位置,删除的项数
插入: 3个参数,起始位置,删除的项数,插入的项
替换:任意参数,起始位置,删除的项数,插入的任意数量的项
```
var colors = ["red", "green", "blue"];
var removed = colors.splice(0,1); // 删除第一项
alert(colors); // green,blue
alert(removed); // red,返回数组中只包含一项
removed = colors.splice(1, 0, "yellow", "orange"); // 从位置1开始插入两项
alert(colors); // green,yellow,orange,blue
alert(removed); // 返回的数组是一个空数组
removed = colors.splice(1, 1, "red", "purple"); // 从位置I开始插入两项
alert(colors); // green,red,yellow,orange,blue
alert(removed); // yellow,返回的数组中只包含一项
```
indexOf()和lastIndexOf():接受两个参数,要查找的项(可选)和查找起点位置的索引
indexOf():从数组开头向后查找
lastIndexOf():从数组末尾开始向前查找
every():对数组中的每一项运行给定函数,如果该函数对每一项都返回true,则返回true。
filter():对数组中的每一项运行给定函数,返回该函数会返回true的项组成数组。
forEach():对数组的每一项运行给定函数,这个方法没有返回值。
map():对数组的每一项运行给定函数,返回每次函数调用的结果组成的数组。
some():对数组的每一项运行给定参数,如果该函数对任一项返回true,则返回true。以上方法都不会修改数组中的包含的值。
reduce()和reduceRight():缩小数组的方法,这两个方法都会迭代数组的所有项,然后构建一个最终返回的值。
join(separator):将数组的元素组起一个字符串,以separator为分隔符,省略的话则用默认用逗号为分隔符
```
var a = [1,2,3,4,5];
var b = a.join("|"); //a:[1,2,3,4,5] b:"1|2|3|4|5"
```
####Array对象自带的排序函数底层是怎么实现的
####数组去重
```
思路:
1.创建一个新的数组存放结果
2.创建一个空对象
3.for循环时,每次取出一个元素与对象进行对比,如果这个元素不重复,则把它存放到结果数组中,同时把这个元素的内容作为对象的一个属性,并赋值为1,存入到第2步建立的对象中。
说明:至于如何对比,就是每次从原数组中取出一个元素,然后到对象中去访问这个属性,如果能访问到值,则说明重复。
Array.prototype.unique3 = function(){
var res = []; // 创建一个新的数组存放结果
var json = {}; // 创建一个空对象
for(var i = 0; i < this.length; i++){
if(!json[this[i]]){ // json不为空的时候
res.push(this[i]); // 把元素依次放入到res中
json[this[i]] = 1; //?
}
}
return res; // 返回res
}
var arr = [112,112,34,'你好',112,112,34,'你好','str','str1'];
alert(arr.unique3()); // 调用unique3函数
```
####数组去除一个函数。
用arr.splice。又问splice返回了什么?应该返回的是去除的元素。
####你知道伪数组吗
这里把符合以下条件的对象称为伪数组:
1,具有length属性
2,按索引方式存储数据
3,不具有数组的push,pop等方法
如
1,function内的**arguments** 。
2,通过**document.forms,Form.elements,Select.options,document.getElementsByName()** **,document.getElementsByTagName()** ,[**childNodes/children** ](http://snandy.iteye.com/blog/547369)等方式获取的集合(HTMLCollection,NodeList)等。
3,特殊写法的对象 ,如
```
var obj={};
obj[0] = "一";
obj[1] = "二";
obj[2] = "三";
obj.length = 3;
```
####那你重新设计一下这个函数,让它直接拥有数组的方法吧
```
// 方法一、 声明一个空数组,通过遍历伪数组把它们重新添加到新的数组中,大家都会,这不是面试官要的
var aLi = document.querySelectorAll('li');
var arr = [];
for (var i = 0; i < aLi.length; i++) {
arr[arr.length] = aLi[i]
}
// 方法二、使用数组的slice()方法 它返回的是数组,使用call或者apply指向伪数组
var arr = Array.prototype.slice.call(aLi);
```
####实现sum(2,3);sum(2,3,4);sum(2,3,4,5);
(我用了比较原始的方法,if来判断)
####那如果sum里面的参数不确定呢
(提取arguments的长度,用for循环)
####手写一个递归函数(考察arguments.callee,以及arguments的解释)
```
// arguments.callee 是一个指向正在执行函数的指针
function factorial(num) {
if (num <= 1) {
return 1;
}
else {
return num * arguments.callee(num - 1);
}
}
```
####若干个数字,怎么选出最大的五个
###AJAX
--------------------------------------------
#### ajax原理
Ajax的原理:通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用javascript来操作DOM而更新页面。
####原生ajax的四个过程/手写原生ajax
a:new一个XHR对象
b:调用open方法
c:send一些数据
d:对过程进行监听,来知道服务器是不是正确地做出了响应,接着可以做一些事情
```
// GET请求:
document.getElementById("search").onclick = function() {
var request = new XMLHttpRequest();
request.open("GET", "server.php?number=" + document.getElementById("keyword").value);
request.send();
request.onreadystatechange = function() {
if (request.readyState===4) {
if (request.status===200) {
document.getElementById("searchResult").innerHTML = request.responseText;
} else {
alert("发生错误:" + request.status);
}
}
}
}
// POST请求
document.getElementById("save").onclick = function() {
var request = new XMLHttpRequest();
request.open("POST", "server.php");
var data = "name=" + document.getElementById("staffName").value
+ "&number=" + document.getElementById("staffNumber").value
+ "&sex=" + document.getElementById("staffSex").value
+ "&job=" + document.getElementById("staffJob").value;
request.setRequestHeader("Content-type","application/x-www-form-urlencoded");
request.send(data);
request.onreadystatechange = function() {
if (request.readyState===4) {
if (request.status===200) {
document.getElementById("createResult").innerHTML = request.responseText;
} else {
alert("发生错误:" + request.status);
}
}
}
}
```
####通过哪个属性得到data?
jquery里是success回调里面的形参。
responseText和responseXML。后者是XML解析了的。
#### readyState几个状态的含义
readyState属性的变化代表服务器响应的变化
0:请求未初始化,open还没有调用
1:服务器连接已建立,open已经调用了
2:请求已接收,也就是接收到头信息了
3:请求处理中,也就是接收到了响应主体
4:请求已完成,且响应已就绪,也就是响应完成了
####支持哪些数据格式?
常用的有三种数据格式:HTML、XML、JSON。
####XML和JSON有过了解吧?能说一下分别介绍一下他们吗?JSON有什么优势
>**XML**:扩展标记语言 (ExtensibleMarkup Language, XML) ,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。
优点:
- A.格式统一,符合标准;
- B.容易与其他系统进行远程交互,数据共享比较方便。
缺点:
- A.XML文件庞大,文件格式复杂,传输占带宽;
- B.服务器端和客户端都需要花费大量代码来解析XML,导致服务器端和客户端代码变得异常复杂且不易维护;
- C.客户端不同浏览器之间解析XML的方式不一致,需要重复编写很多代码;
- D.服务器端和客户端解析XML花费较多的资源和时间。
>**JSON**:(JavaScript ObjectNotation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。 JSON采用完全独立于语言的文本格式。
优点:
- A.数据格式比较简单,易于读写,格式都是压缩的,占用带宽小;
- B.易于解析,客户端JavaScript可以简单的通过eval()进行JSON数据的读取;
- C.支持多种语言。包括ActionScript, C, C#, ColdFusion, Java, JavaScript, Perl, PHP, Python, Ruby等服务器端语言,便于服务器端的解析;
- D.在PHP世界,已经有PHP-JSON和JSON-PHP出现了,偏于PHP序列化后的程序直接调用,PHP服务器端的对象、数组等能直接生成JSON格式,便于客户端的访问提取;
- E.因为JSON格式能直接为服务器端代码使用,大大简化了服务器端和客户端的代码开发量,且完成任务不变,并且易于维护。
缺点:
- A.没有XML格式这么推广的深入人心和喜用广泛,没有XML那么通用性;
- B.JSON格式目前在Web Service中推广还属于初级阶段。
####在不支持json格式的浏览器中,写方法能够将json字符串与对象互相转换;
现代浏览器中提供了JSON.stringify()方法 将数组,对象转成json。
JSON.stringify 把一个对象转换成json字符串,
JSON.parse 把一个json字符串解析成对象。
####ajax在jquery的底层是怎么实现的
####手写一个promise版的ajax
####js的异步加载,promise的三种状态,ES7中的async用过么
####如果页面初始载入的时候把ajax请求返回的数据存在localStorage里面,然后每次调用的时候去localStorage里面取数,是否可行。
(直接说了不能保证数据的实时性,请求和实时性必然会有一方有所牺牲)
####js异步的方法
方案一:`<script>`标签的`async="async"`属性(详细参见:script标签的async属性)
点评:HTML5中新增的属性,Chrome、FF、IE9&IE9+均支持(IE6~8不支持)。此外,这种方法不能保证脚本按顺序执行。
方案二:`<script>`标签的`defer="defer"`属性
点评:兼容所有浏览器。此外,这种方法可以确保所有设置defer属性的脚本按顺序执行。
方案三:动态创建`<script>`标签
```
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
(function() {
var s = document.createElement_x('script');
s.type = 'text/javascript';
s.src = "http://code.jquery.com/jquery-1.7.2.min.js";
var tmp = document.getElementsByTagName_r('script')[0];
tmp.parentNode.insertBefore(s, tmp);
})();
</script>
</head>
<body>
![](http://xybtv.com/uploads/allimg/100601/48-100601162913.jpg)
</body>
</html>
```
点评:兼容所有浏览器。
方案四:AJAX eval(使用AJAX得到脚本内容,然后通过eval_r(xmlhttp.responseText)来运行脚本)
点评:兼容所有浏览器。
方案五:iframe方式(这里可以参照:iframe异步加载技术及性能 中关于Meboo的部分)
点评:兼容所有浏览器。
###跨域
---------------------------------------------------
####jsonp是什么
JSON是一种数据格式,JSONP是一种数据调用方式。
工作原理:
利用`<script>`标签没有跨域限制的来达到与第三方通讯的目的。
当需要通讯时,本站脚本创建一个`<script>`元素,地址指向第三方的API网址,形如: `<script src="http://www.example.net/api?param1=1¶m2=2"></script>` 并提供一个回调函数来接收数据(函数名可约定,或通过地址参数传递)。 第三方产生的响应为json数据的包装(故称之为jsonp,即json padding),形如: `callback({"name":"hax","gender":"Male"})`这样浏览器会调用callback函数,并传递解析后json对象作为参数。本站脚本可在callback函数里处理所传入的数据。
```
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<script type="text/javascript">
function jsonpCallback(result) {
//alert(result);
for(var i in result) {
alert(i+":"+result[i]);//循环输出a:1,b:2,etc.
}
}
var JSONP=document.createElement("script");
JSONP.type="text/javascript";
JSONP.src="http://crossdomain.com/services.php?callback=jsonpCallback";
document.getElementsByTagName("head")[0].appendChild(JSONP);
</script>
// 或者:
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<script type="text/javascript">
function jsonpCallback(result) {
alert(result.a);
alert(result.b);
alert(result.c);
for(var i in result) {
alert(i+":"+result[i]);//循环输出a:1,b:2,etc.
}
}
</script>
<script type="text/javascript" src="http://crossdomain.com/services.php?callback=jsonpCallback"></script>
```
####手写jsonp
####jsonp怎么用
动态加载`<script>`标签
####!发送jsonp时候的那个消息头长什么样子
####跨域是啥
跨域是指 不同域名之间相互访问
协议、子域名、主域名、端口号任意一个不相同时,都算跨域。
####跨域了解多少
讲了CORS、JSONP、postMessage啥的
####跨域的方法
1. JSONP
- 原理:
动态`<script>`标签
`<script>` 标签是不受同源策略的限制的,它可以载入任意地方的 JavaScript 文件,而并不要求同源。
- 例子:
```
<script>function getWeather(data) { console.log(data); }</script>
<script src="http://x.y.com/xx.js">
// http://x.y.com/xx.js 文件内容:
getWeather({
"城市": "北京",
"天气": "大雾"
});
```
2. document.domain
- 使用条件:
1.有其他页面 window对象的引用。
2.二级域名相同。
3.协议相同。
4.端口相同。
3. window.name
4. [HTML5] postMessage
####前端跨域方法以及说下怎样实现
JSONP XHR2 后端代理 window.name window.postmessage
异步:客户端的操作和服务器端的操作互相之间不会造成堵塞
XMLHttpRequest对象:后台和服务器交换数据
1、利用html+css来实现页面,表达信息;
2、用XMLHttpRequest和web服务器进行数据的异步交换
3、运营js操作DOM,实现动态局部刷新;
####!为什么要跨域
####描述一下跨域安全问题
####Cookie跨域请求能不能带上
###this
----------------------------------------
####js中this的作用
####this的理解
当执行的对象
####怎么传入this
call apply
####this作用域:
####apply和call的区别
foo.call(this, arg1,arg2,arg3) == foo.apply(this, arguments)
`call方法`:
语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]])
定义:调用一个对象的一个方法,以另一个对象替换当前对象。
说明:
call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。
`apply方法`:
**• 在js里call()与apply()有什么相同和不同? **
>apply()方法:
接受两个参数,一个是在其中运行函数的作用域,另一个是参数数组(可以是Array的实例,也可以是arguments对象)。
语法:apply(thisObj,[argArray])
定义:应用某一对象的一个方法,用另一个对象替换当前对象。
```
function sum(num1,num2){
return num1 + num2;
}
function callsum1(num1,num2){
return sum.apply(this,[num1,num2]);//传入数组
}
function callsum2(num1,num2){
return sum.apply(this,arguments);//传入arguments对象
}
alert(callsum1(10,10));
alert(callsum2(10,10));
```
>call()方法:
他与apply()方法的区别仅在与接收参数的方式不同。对于call()方法而言,第一个参数是this值没有变化变化的是其余参数都直接传递个函数。换句话说就是在使用call()方法时,传递给函数的参数必须逐个例举出来。
语法:call(thisObj,Object)
定义:调用一个对象的一个方法,以另一个对象替换当前对象。
```
function sum(num1,num2){
return num1 + num2;
}
function callsum(num1,num2){
return sum.call(this, num1, num2);
}
alert(callsum(10,10));
```
####实现bind函数
####js中上下文是什么
####js有哪些函数能改变上下文
call apply
###事件
-----------------------------------------------
####实现事件代理
事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。
例1:点击li,弹出123
```
<ul id="ul1">
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
</ul>
// 实现功能是点击li,弹出123:
window.onload = function(){
var oUl = document.getElementById("ul1");
var aLi = oUl.getElementsByTagName('li');
for(var i = 0; i < aLi.length; i++){
aLi[i].onclick = function(){
alert(123);
}
}
}
// 事件委托:利用冒泡
window.onload = function(){
var oUl = document.getElementById("ul1");
oUl.onclick = function(){
alert(123);
}
}
// 事件委托:点击具体的Li才会发生
window.onload = function(){
var oUl = document.getElementById("ul1");
oUl.onclick = function(ev){
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
if(target.nodeName.toLowerCase() == 'li'){
alert(123);
alert(target.innerHTML);
}
}
}
```
例2:每个li点击的效果都不一样
```
<div id="box">
<input type="button" id="add" value="添加" />
<input type="button" id="remove" value="删除" />
<input type="button" id="move" value="移动" />
<input type="button" id="select" value="选择" />
</div>
// 普通方法:
window.onload = function(){
var Add = document.getElementById("add");
var Remove = document.getElementById("remove");
var Move = document.getElementById("move");
var Select = document.getElementById("select");
Add.onclick = function(){
alert('添加');
};
Remove.onclick = function(){
alert('删除');
};
Move.onclick = function(){
alert('移动');
};
Select.onclick = function(){
alert('选择');
}
}
// 事件委托:
window.onload = function(){
var oBox = document.getElementById("box");
oBox.onclick = function (ev) {
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
if(target.nodeName.toLocaleLowerCase() == 'input') {
switch(target.id){
case 'add' :
alert('添加');
break;
case 'remove' :
alert('删除');
break;
case 'move' :
alert('移动');
break;
case 'select' :
alert('选择');
break;
}
}
}
}
```
总结:
那什么样的事件可以用事件委托,什么样的事件不可以用呢?
适合用事件委托的事件:click,mousedown,mouseup,keydown,keyup,keypress。
值得注意的是,mouseover和mouseout虽然也有事件冒泡,但是处理它们的时候需要特别的注意,因为需要经常计算它们的位置,处理起来不太容易。
####事件代理中怎么定位实际事件产生的目标
A:捕获->处于目标->冒泡,IE应该是只有冒泡没有捕获。
事件代理就是在父元素上绑定事件来处理,通过event对象的target来定位。
####jquery的委托原理
####冒泡和捕获,事件流哪三个阶段?
除了冒泡和捕获,还有目标阶段。他们的先后顺序,先捕获,到了目标,再冒泡。(不要只记概念,要了解是干么用的)
```
DOM事件流包括三个阶段:
事件捕获阶段
处于目标阶段
事件冒泡阶段
```
####事件机制,如何绑定事件处理函数
[浅谈JavaScript的事件机制](http://blog.csdn.net/wusuopubupt/article/details/21738523)
[JavaScript绑定事件的方法[3种]](http://www.itxueyuan.org/view/6338.html)
####事件类型、绑定方式
```
1、表单事件:
submit事件、reset事件、click事件、change事件、
focus事件(不冒泡) (IE和ES5支持冒泡的focusin)
blur事件(不冒泡) (IE和ES5支持冒泡的focusout)
input事件(ES5 textinput提供更方便的获取输入文字的方案)
2、Window事件
load事件、DOMContentLoaded事件、readyStatechage事件
unload事件、beforeunload事件、resize事件、scroll事件
3、鼠标事件
click事件、dbclick事件、mouseover事件(冒泡)、
mouseout事件(冒泡)、mousedown事件、mouseup事件
contextmenu事件、mouseenter事件(不冒泡)、mouseleave事件(不冒泡)
mousewheel事件(FF DOMMouseScroll事件、DOM3 wheel事件)
4、键盘事件
keydown事件、keyup事件、keypress事件
```
####w3c事件与IE事件的区别 (当时回答的只想到冒泡跟捕获)
####IE与W3C怎么阻止事件的冒泡
当我们需要阻止浏览器某DOM元素的默认行为:
W3C用e.preventDefault()
IE下用window.event.returnValue=false
阻止事件冒泡:
W3C用e.stopPropagation()
IE下用window.event.cancelBubble=true来实现。
>在浏览器解析事件的时候,有两种触发方式,一种叫做Bubbling(冒泡),另外一种叫做Capturing(捕获)。由上图可以看出来,冒泡的方式效果就是当一个DOM元素的某事件例如click事件被fire时,依次它的父元素的click事件也被fire(触发),一直传递到最顶层的body元素为止。而捕获的触发方式正好相反,当某个元素的click事件被触发时,先从最顶层的body元素click事件被触发开始,一直传递到真正被触发的元素为止。
>这次我将讨论W3C的标准DOM事件模型和IE独立门户的DOM事件模型到底有多少区别,首先我们可以回想一下目前大多数Js程序员习惯如何绑定事件到DOM元素上,最常见的就是obj.onclick=handler这种方式(更恶劣的是在Html代码的元素标签中直接加上onclick属性,完全没达到视图和动作分开的原则)。我们暂时称这种方式的事件添加为Traditional(传统方式)吧,IE有自己的IE Event Module,而火狐等浏览器则遵循的W3C方式的Event Module,下面看看这三者各自的优缺点在哪里——
>1、 Traditional Module
>传统方式的事件模型即直接在DOM元素上绑定事件处理器,例如—
>window.onload=function(){…}
>obj.onmouseover=function(e){…}
>obj.onclick=function(){…}
>首先这种方式是无论在IE还是Firefox等其他浏览器上都可以成功运行的通用方式。这便是它最大的优势了,而且在Event处理函数内部的this变量无一例外的都只想被绑定的DOM元素,这使得Js程序员可以大大利用this关键字做很多事情。
>至于它的缺点也很明显,就是传统方式只支持Bubbling,而不支持Capturing,并且一次只能绑定一个事件处理器在DOM元素上,无法实现多Handler绑定。最后就是function参数中的event参数只对非IE浏览器有效果(因为IE浏览器有特制的window.event)。
>2、 W3C (Firefox.e.g) Event Module
>Firefox等浏览器很坚决的遵循W3C标准来制定浏览器事件模型,使用addEventListener和removeEventListener两个函数,看几个例子—
>window.addEventListener(‘load’,function(){…},false);
>document.body.addEventListener(‘keypress’,function{…},false);
>obj.addEventListener(‘mouseover’,MV,true);
>function MV(){…}
>addEventListener带有三个参数,第一个参数是事件类型,就是我们熟知的那些事件名字去掉前面的’on’,第二个参数是处理函数,可以直接给函数字面量或者函数名,第三个参数是boolean值,表示事件是否支持Capturing。
>W3C的事件模型优点是Bubbling和Capturing都支持,并且可以在一个DOM元素上绑定多个事件处理器,各自并不会冲突。并且在处理函数内部,this关键字仍然可以使用只想被绑定的DOM元素。另外function参数列表的第一个位置(不管是否显示调用),都永远是event对象的引用。
>至于它的缺点,很不幸的就只有在市场份额最大的IE浏览器下不可使用这一点。
>3、 IE Event Module
>IE自己的事件模型跟W3C的类似,但主要是通过attachEvent和detachEvent两个函数来实现的。依旧看几个例子吧—
>window.attachEvent(‘onload’,function(){…});
>document.body.attachEvent(‘onkeypress’,myKeyHandler);
>可以发现它跟W3C的区别是没有第三个参数,而且第一个表示事件类型的参数也必须把’on’给加上。这种方式的优点就是能绑定多个事件处理函数在同一个DOM元素上。
>至于它的缺点,为什么如今在实际开发中很少见呢?首先IE浏览器本身只支持Bubbling不支持Capturing;而且在事件处理的function内部this关键字也无法使用,因为this永远都只想window object这个全局对象。要想得到event对象必须通过window.event方式,最后一点,在别的浏览器中,它显然是无法工作的。
>最后我在推荐两个必须知道的IE和W3C标准的区别用法吧—
>1、 当我们需要阻止浏览器某DOM元素的默认行为的时候在W3C下调用e.preventDefault(),而在IE下则通过window.event.returnValue=false来实现。
>2、当我们要阻止事件冒泡的时候,在W3C标准里调用e.stopPropagation(),而在IE下通过设置window.event.cancelBubble=true来实现。
####描述一下事件模型
####IE的事件模型是怎样的
####event对象/事件包括哪些东西
####js异步模式如何实现
[Javascript异步编程的4种方法](http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html)
####手写一个盒子模型中,获取盒子内子节点的class样式,盒子内节点的类型不可知
我用了事件监听,但没考虑浏览器兼容性,也没能写出来怎么判定节点的类型(枚举不可)
面试官问我自己给这个代码打几分,我说60分
面试官说这种代码兼容性有问题,根本不能在线上运行,所以60分也没QwQ
使用事件代理机制,当事件被抛到更上层的父节点的时候,我们通过检查事件的目标对象(target)来判断并获取事件源。 // 获取父节点,并为它添加一个click事件 document.getElementById("parent-list").addEventListener("click",function(e) { // 检查事件源e.targe是否为Li if(e.target && e.target.nodeName.toUpperCase() == "LI") { // 真正的处理过程在这里 //alert(123); console.log("List item ",e.target.id," was clicked!");
}
});
• 事件捕获:当某个元素触发某个事件(如onclick),顶层对象document就会发出一个事件流,随着DOM树的节点向目标元素节点流去,直到到达事件真正发生的目标元素。在这个过程中,事件相应的监听函数是不会被触发的。
• 事件目标:当到达目标元素之后,执行目标元素该事件相应的处理函数。如果没有绑定监听函数,那就不执行。
• 事件起泡:从目标元素开始,往顶层元素传播。途中如果有节点绑定了相应的事件处理函数,这些函数都会被一次触发。如果想阻止事件起泡,可以使用e.stopPropagation()(Firefox)或者e.cancelBubble=true(IE)来组织事件的冒泡传播。
###JQ
-----------------------------------------------
####jQuery还是原生js
####为什么选择原生
我认为要把原生吃透再去理解其他类库的话会更好一点,她说也是
#### jQuery源码有看过吗?请说出jQuery内部判断数据类型的巧妙方式
####jQuery源码有看过吗?请说出你印象最深刻部分的原理。
####手写一个jQuery插件
####在jquery方法和原型上面添加方法的区别和实现($.extend,$.fn.extend),以及jquery对象的实现(return new jQuery.fn.init)
####手写实现jquery里面的insertAfter
(结合nextSibling和insertBefore来实现)
####jquery和zepto有什么区别
###es6
-----------------------------------------
####es6与es7了解多少
####谈谈对ES6的理解
####es6的新特性
####promise let关键字,class ,
####promise
`http://www.jianshu.com/p/063f7e490e9a`
####Promise编程
####手写实现一个promise(不会)
####如何避免多重回调—promise,promise简单描述一下,如何在外部进行resolve()
####promise解决了你什么问题
####ES5中,除了函数,什么能够产生作用域
A:对象?
//然后被回问对象有作用域吗?然后我说对象里面this会变。。。完全把作用域和执行环境弄混了
####es6中字符串模版怎么用
####ES6里头的箭头函数的this对象与其他的有啥区别
###浏览器
-------------------------------------------
####浏览器端的JS包含哪几个部分
ECMAScript+DOM
####浏览器渲染的方式
####浏览器的渲染过程
(如js代码什么时候运行啊,css代码上面时候渲染啊,js代码运行阻塞页面渲染之类的)
####浏览器加载一个页面的过程、渲染机制
浏览器的解析方式,浏览器解析html页面首先浏览器先下载html,然后在内存中把html代码转化成Dom Tree,然后浏览器根据Dom Tree上的Node分析css和Images,当文档下载遇到js时,js独立下载。
###DOM
--------------------------------------------------------------
####DOM包含哪些对象?
Node对象,然后继承下来的有Document,Element,Text,还有想不起来了
https://zhidao.baidu.com/question/562272490.html
####如何获取某个DOM节点,节点遍历方式
####setTimeout和setInterval区别,如何互相实现?
setInterval在执行完一次代码之后,经过了那个固定的时间间隔,它还会自动重复执行代码,而setTimeout只执行一次那段代码。
区别:
```
window.setTimeout("function",time);//设置一个超时对象,只执行一次,无周期
window.setInterval("function",time);//设置一个超时对象,周期='交互时间'
```
####了解navigator对象吗
Navigator 对象:
Navigator 对象包含有关浏览器的信息。
注释:没有应用于 navigator 对象的公开标准,不过所有浏览器都支持该对象。
###缓存
------------------------------------------------
####cookie与session的区别
[Cookies 和 Session的区别](http://blog.csdn.net/axin66ok/article/details/6175522)
[COOKIE和SESSION有什么区别?](https://www.zhihu.com/question/19786827)
####Cookie 是否会被覆盖,localStorage是否会被覆盖。
同名cookie会被覆盖
####cookie和session有什么区别
cookie在客户端,session在服务端
####浏览器在发送cookie时会发送哪几个部分?
A:不太清楚
####那你知道cookie有哪几个组成部分吗?
A:不太清楚
Cookie由变量名和值组成,类似[JavaScript](http://lib.csdn.net/base/javascript)变量。其属性里既有标准的Cookie变量,也有用户自己创建的变量,属性中变量是用“变量=值”形式来保存。
####你有用开发者工具看过cookie吗
A:有
####浏览器缓存的区别
###前端安全
--------------------------------------
####前端安全
[聊一聊WEB前端安全那些事儿](https://segmentfault.com/a/1190000006672214)
####前端安全:xss攻击和csrf
**XSS跨站脚本(Crosssite scripting)**
原因:XSS其实就是Html的注入问题,攻击者的输入没有经过严格的控制进入了数据库,最终显示给来访的用户,导致可以在来访用户的浏览器里以浏览用户的身份执行Html代码。
攻击手段和目的:
攻击者使被攻击者在浏览器中执行脚本后,如果需要收集来自被攻击者的数据(如cookie或其他敏感信息),可以自行架设一个网站,让被攻击者通过JavaScript等方式把收集好的数据作为参数提交,随后以数据库等形式记录在攻击者自己的服务器上。
a. 盗用 cookie ,获取敏感信息。
b.利用植入 Flash ,通过 crossdomain 权限设置进一步获取更高权限;或者利用Java等得到
类似的操作。
c.利用 iframe、frame、XMLHttpRequest或上述Flash等方式,以(被攻击)用户的身份执行一
些管理动作,或执行一些一般的如发微博、加好友、发私信等操作。
d.利用可被攻击的域受到其他域信任的特点,以受信任来源的身份请求一些平时不允许的操
作,如进行不当的投票活动。
e.在访问量极大的一些页面上的XSS可以攻击一些小型网站,实现DDoS攻击的效果。
避免XSS的方法:
1.主要是将用户所提供的内容进行滤;
移除用户上传的dom结点,比如onerror;
移除用户上传的style结点,script结点,iframe结点等。
2.使用HTTP头指定类型:
很多时候可以使用HTTP头指定内容的类型,使得输出的内容避免被作为HTML解析。如在PHP语言中使用以下代码:
```
header
('Content-Type: text/javascript; charset=utf-8');
```
即可强行指定输出内容为文本/JavaScript脚本(顺便指定了内容编码),而非可以引发攻击的HTML。
**CSRF(伪造请求):冒充用户之手**
CSRF 顾名思义,是伪造请求,冒充用户在站内的正常操作。我们知道,绝大多数网站是通过 cookie 等方式辨识用户身份(包括使用服务器端 Session 的网站,因为 Session ID 也是大多保存在 cookie 里面的),再予以授权的。所以要伪造用户的正常操作,最好的方法是通过XSS 或链接欺骗等途径,让用户在本机(即拥有身份 cookie 的浏览器端)发起用户所不知道的请求。
防御方法:
请求令牌(一种简单有效的防御方法):
首先服务器端要以某种策略生成随机字符串,作为令牌(token),保存在 Session 里。然后在发出请求的页面,把该令牌以隐藏域一类的形式,与其他信息一并发出。在接收请求的页面,把接收到的信息中的令牌与 Session 中的令牌比较,只有一致的时候才处理请求,处理完成后清理session中的值,否则返回 HTTP 403 拒绝请求或者要求用户重新登陆验证身份。
###功能实现
---------------------------------------
####1.一个文本框,需要两个控件对里面的值进行控制,一个是+1一个是-1,要求每点击一次就有个提示框冒出来。 而且文本框是可修改的,每次修改也会冒出提示框。( 事件监听)
####2.使用js画一个抛物线,抛物线上有个小球随着抛物线运动,有两个按钮能使小球继续运动停止运动
####3.js轮播实现思路
####4.实现一个querySelectorAll的功能
函数长这样querySelect(el, className)
```
function querySelect(el,className){
var children = el.children;
var result = [];
if(el.classList.contains(className)){
result.push(el);
}
for(var i; i<children.length; i++){
var child = children[i];
var arr = querySelect(child,className);
result.push.apply(result, arr);
}
return result;
}
```
####5.实现一个快排
```
#include <iostream>
using namespace std;
void Qsort(int a[], int low, int high)
{
if(low >= high)
{
return;
}
int first = low;
int last = high;
int key = a[first];/*用字表的第一个记录作为枢轴*/
while(first < last)
{
while(first < last && a[last] >= key)
{
--last;
}
a[first] = a[last];/*将比第一个小的移到低端*/
while(first < last && a[first] <= key)
{
++first;
}
a[last] = a[first];
/*将比第一个大的移到高端*/
}
a[first] = key;/*枢轴记录到位*/
Qsort(a, low, first-1);
Qsort(a, first+1, high);
}
int main()
{
int a[] = {57, 68, 59, 52, 72, 28, 96, 33, 24};
Qsort(a, 0, sizeof(a) / sizeof(a[0]) - 1);/*这里原文第三个参数要减1否则内存越界*/
for(int i = 0; i < sizeof(a) / sizeof(a[0]); i++)
{
cout << a[i] << "";
}
return 0;
}/*参考数据结构p274(清华大学出版社,严蔚敏)*/
```
####lazyload如何实现
[图片懒加载](图片延迟加载(lazyload)的实现原理)
###移动端
---------------------------------------------
####移动端是指手机浏览器,还是native,还是hybrid(问这个问题真的是无语)
####你用了移动端的什么库类和框架?
####移动端要注意哪些
####移动端是指手机浏览器,还是native,还是hybrid(问这个问题真的是无语)
####你用了移动端的什么库类和框架?
####移动端要注意哪些
####适配有去考虑么,retina屏幕啊?
####rem是什么?em是什么?如果上一层就是根root了,em和rem等价么?
#### 你对目前流行的前端框架都有什么了解,有没有应用经验?
(一面时面试官推荐我多了解一下 Vue.js ,我回去也恶补了,二面时便说了一些对Vue.js的理解,二面面试官也说Vue.js是他们常用的,这个信息很重要)
###算法
####双向链表怎么找中点?
头尾指针都往中间走,两个指针相等或交替的时候为中点
####上面的问题 单向链表呢
A:先走到尾记下有几个元素,然后再走到一半的地方
//面完查了下可以用快慢指针,一个指针每次走一步,另外个走两步,快指针到尾部时慢指针在中点
###问答
####1
obj怎么变?
```
var obj = {
a : 1
};
(function (obj) {
obj = {a : 2};
})(obj);
```
A:外面的obj不变,因为里面等于让局部的obj指向了一个新的对象
```
var obj = {
a: 1,
func: function() {
(function() {
a = 2;
}();
}
};
obj.func();
```
####2
问a怎么变匿名函数里的this是什么?怎么改变里面的this?匿名函数不能传参怎么改变obj.a的值?
A: obj.a不变,匿名函数里的this指向全局对象(window),相当于给window加了一个名为a的属性。
```
(function () {
this.a = 2;
}).call(this);
//或者apply
//或者
func: function () {
var self = this;
(function () {
self.a = 2;
})();
}
```
###其他
####4. 字符串“1”加上数字1的结果是?
(也许是看我前一题答不上来,沉默半天突然问了这个……这是在动态调整难度?)
####JS动画有哪些实现方法
####那你知道还有什么实现动画的方法
A:CSS3的animation,还有用canvas做的算吗?
####做一些js题(考察this,作用域,变量声明,引用类型);
####实现一个列表中每个li里有一个input和button,点击button删除对应的li节点
#### 给了段代码,问输出什么。主要是考作用域链和this
####要实现函数内每隔5秒调用自己这个函数,100次以后停止,怎么办
###框架
####介绍一下react
####组件化是啥
####你觉的react的优点
####为什么没有选择学习AngularJS
####主流框架Node Angular Vue React对比 javascript实现的底层原理 **
####bootstrap的实现原理
####vue与angularjs区别
####对nodejs了解多少
####nodejs中的文件怎么读写
####解释一下vue和react,以及异同点
####解释一下react和vue,以及区别
####requireJS的原理是什么
####require的读取顺序
####手写实现requireJS模块实现(想了半天才想到createElement("script"),配合异步来加载,闭包导出)
####react和vue的介绍以及异同
####AMD和CMD,commonJS的区别
####requirejs如何避免循环依赖
####vue的特点?双向数据绑定是如何实现的
####学习angularjs之类的库的方法
####5requirejs实现原理
####5.vuejs与angularjs的区别
####requirejs怎么防止重复加载
####vue如何实现父子组件通信,以及非父子组件通信
####vuex是用来做什么的 /说下你所了解的vuex
###打包工具
####为什么要打包
(我说了http请求那点事)
####介绍一下webpack和gulp,以及项目中具体的使用
####gulp的插件用过啥/gulp用过啥
####gulp底层实现原理
####gulp你是怎么用的
####webpack底层实现原理
####gulp与webpack区别
####webpack是用来干嘛的
####webpack与gulp的区别
####vue源码结构
####vue与angularjs中双向数据绑定是怎样实现的
####webpack怎样配置
####angular的双向绑定原理
####angular和react的认识(挖财用这个两个框架,后来问了)
####MVVM是什么
####说说你了解的框架
我说了react和vue
####react你觉得怎样
(我说了一些组件化和虚拟dom树的东西)
####AngularJS呢
(我说没有学过,但了解过一点,我把我了解的都说了给她听)
####为什么你会觉得AngularJS笨重?
(也是自己的看法,mvc框架嘛,一整套什么都有)
####响应式布局是啥
一个网站能够兼容多个终端
####响应式布局是根据什么进行响应
通过定义容器大小,平分12份(也有平分成24份或32份,但12份是最常见的),再调整内外边距,最后结合媒体查询,就制作出了响应式网格系统。
判断出终端设备的容器宽度,然后选择性的加载吻合大小的网页,也就是媒体查询。媒体查询写在CSS样式代码的最后,CSS是层叠样式表,在同一特殊性下,靠后的的样式会重叠前面的样式。
html头部也要写兼容性,例如:`<meta name="viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"/>`。
注释:
`width=device-width`:宽度等于当前设备的宽度
`initial-scale=1`:初始的缩放比例(默认为1)
`maximum-scale=1`:允许用户缩放到得最大比例(默认为1)
`user-scalable=no`:用户不能手动缩放
####响应式布局的方式
如何实现响应式布局?
1、百分比
通过将每个盒子的宽度设定百分比来实现。
优点:简单方便要
缺点:在额外设置margin、padding时,或者使用不同浏览器时,会使得布局混乱
2、meta标签
代码段为:
`<meta name="viewport" content="width=device-width, initial-scale=1" /> `
这主要是为了让代码适应移动端的屏幕,其中,viewport 是指需要加载meta 标签时读取的名字为“视口”,其中的 width 需要等于 device-width(设备宽度),主要是告诉浏览器,将布局视口的宽度设置为设备最理想的宽,initial-scale(缩放比例) 为1,这样就保证了加载的时候,要获取设备的宽度,同时要保持原始大小,便于媒体查询
3、@media 媒体查询
css代码段为:
`@media screen and (min-width: 10rem) and (max-width: 20rem) { ... } `
这里面的 第一个 screen 意思为屏幕,这里面还有许多 参数,包括all(用于所有设备)、print(用于打印机和打印预览)、speech(应用于屏幕阅读器等发声设备)。
使用and来并列显示多种情况,min-width 和max-width 来定义在那种尺寸的屏幕上显示,这就是响应式的灵魂。
上面的例子,就是 媒体查询屏幕,最小宽度为10rem 最大宽度我20rem 的设备宽度上来实现大括号内的样式或者其他功能,这里面的rem也可以换成px或者em之类的单位等。
优点:现在大部分的响应式布局都是使用@media 来实现的,可以书写大量的公共样式,在需要适应屏幕的时候,在大括号内加入相应的功能即可实现响应式布局。
缺点:可能需要对同一个类书写不同的样式,代码比较繁复,难度也稍微难点。
###没有
####手写一个js的深克隆
####for函数里面setTimeout异步问题
####原生js模板引擎
####用原生js实现复选框选择以及全选非全选功能
####看过哪些框架的源码
####要求写js自定义事件
####作用域的题
#####js写一个递归。就是每隔5秒调用一个自身,一共100次。
####如何保持登录状态
####原生js添加class怎么添加,如果本身已经有class了,会不会覆盖,怎么保留?
####Get和post的区别
####1.怎么得到一个页面的a标签
(就说了getElementByTagName和选择器)
####2.怎么在页面里放置一个很简单的图标,不能用img和background-img
(说了canvas,或者一些库有icon库,data-icon).
####3.正则表达式判断url(只写了判断是否是http或者https开头)
[正则表达式匹配URL](http://blog.csdn.net/weasleyqi/article/details/7912647)
```
String check = @"((http|ftp|https)://)(([a-zA-Z0-9\._-]+\.[a-zA-Z]{2,6})|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,4})*(/[a-zA-Z0-9\&%_\./-~-]*)?";
```
####4.怎么去除字符串前后的空格
```
(正则匹配^\s和\s$并且替代,Jquery的$.trim,string.trim())
tring.prototype.Trim = function(){return this.replace(/(^\s*)|(\s*$)/g, "");}
g 为全局标志
```
正则表达式,JS里一组特殊的东东,上例是替换文本前与后的空格,就等于trim。
####实现页面的局部刷新
####JavaScript是单线程还是多线程的?
####Javascript 是一种弱类型语言,它分别有什么优点和缺点?
####websocket知道吗?
####知道最近流行哪些前端技术吗?我回答的nodejs
####用js使低版本浏览器支持HTML5标签 底层是怎么实现
####实现一个可拖动的div
**1.用原生JS实现一个接口,能够用Ajax上传文件并显示上传进度,上传完成后接收一个来自服务器的json数据**
####介绍一下主流的框架吧,angular 和react,原理,实现。
我把angular的watch digest这些讲了个遍,也问了关于react的虚拟dom,为什么要这么做,优势在哪里? 使用这些前端的框架的优势是什么,劣势又是什么 。 (看我把原理讲的差不多,问我是不是在网上看了很多的这方面的文章,卧槽竟然别发现了,这些东西都是我面试前一天看的,我立马意识到不对),其实呢,框架对于我来说并不是要熟悉多少它的api,而是要研究它的设计思想,这样对自己以后的编码也是有帮助的哈(成功避开话题)
#### 因为项目中用过很多redis,难免要去解释一下redis的底层实现,
首先说了说底层6大的数据结构,链表,字符串,字典,跳表,压缩列表等,redis是一个基于epoll的单线程模型,redis的应用举例,在你的项目中如何使用,说到设置expire时间的时候,我给自己挖了个坑,面试官问我如何实现定时器,redis中有没有定时器这个概念(其实是没有的)我入坑了, ,后来发现不对劲,赶紧说自己好久没有研究这个底层了,有些概念可能有些模糊了。后来面试官提醒我是用epoll注册事件的方法来实现expire的。自认为redis应该是自己的加分项,没有想到是减分项。
####node.js有用过吗?
A:有,主要用一些工具,比如gulp
####你有用过什么代码管理工具
A://然后面试官看到简历上有GitHub就不问了
####介绍MVVM模式;
####如果要你设计一个组件,你会如何设计
####grunt用过哪些功能;
####浏览器如何匹配某个选择器;
####websocket相关,轮询,polling;
####ws和wss的区别;
###设计模式
####要是让你自己写一个js框架你会用到哪些设计模式
####平常在项目中用到过哪些设计模式,说说看
####了解哪些设计模式说说看
####说下你所了解的设计模式的优点
###其他
####页面优化
####移动端和pc差别
####模块化
####说下你所理解的mvc与mvvc
####有没有上传过些什么npm模块