常见js笔试面试题
1
js基础知识
1. javascript typeof返会的数据类型有哪些
object,string,undefined,number,function,boolean
“数字”、“字符串”、“布尔值”、“对象”、“函数”和“未定义”。
Object 对象或者null返回的是object,数组也返回object
-
基本数据类型:
字符串String、数字Number、布尔Boolean、数组Array、对象Object、Null、Undefined
因为NaN的数据类型就是数字,就是number;他是一个特殊的number。因为在js中数据类型之间都是
可以相互转化的,这方便了其他数据类型转化为number(非数字转化为number类型便是NaN)
2. 列举三种强制类型转换和两种隐式类型转换
parseInt(),parseFloat(),Number()
==,!!(各种比较和计算的运算符)
强制类型转换是得到一个新的东西(你想转换的类型)。
隐式类型转换只是在运算或者比较时转换一下(转换成数值),不产生新东西。
强制是我们需要它转换 ,调用函数主动转换;隐式是被动转换,自动进行。
3. 数组相关集合
-
3.1. 创建数组方法
var array = new Array()
var array = []
Array.of(1,2) //[1,2]
这是es6新增的一个Array方法,创建一个具有可变数量参数的新数组实例,而不考虑参数的数量或类型。
Array.of()方法用于将一组值,转换为数组。
Array.of(3, 11, 8) // [3,11,8]
Array.of(3) // [3]
Array.of(3).length // 1
这个方法的主要目的,是弥补数组构造函数Array()的不足。因为参数个数的不同,会导致Array()的
行为有差异。
Array() // []
Array(3) // [, , ,]
Array(3, 11, 8) // [3, 11, 8]
上面代码中,Array方法没有参数、一个参数、三个参数时,返回结果都不一样。只有当参数个数不少
于 2 个时,Array()才会返回由参数组成的新数组。参数个数只有一个时,实际上是指定数组的长度
。
4. 判断是否为数组的方法
console.log(arr instanceof Array)
instanceof 是一个二元运算符,左边操作数是一个对象,不是的话返回false,右边操作数是一个
函数对象或者函数构造器,不是的话返回false。原理是通过判断左操作数的对象的原型链上是否
具有右操作数的构造函数的prototype属性。
JavaScript中的双目判断运算符,a instanceOf b ,判断a的构造器是否为b(其实只要a与b在一个
原型链中就会返回true,具体请参考:javaaceipt原型链相关内容)。
console.log(arr.constructor === Array)
constructor属性的值是一个函数对象,而且函数指向的正式构造函数(即创建该对象的那个函数)
,所以可以这样判断某个对象是否是某个构造函数的实例。但是对象的constructor属性可以被改
写,改写后用改方法判断就不行了
console.log(Array.isArray(arr))
Array.isArray(obj);ES5出的一个API,专门用来判断一个对象是不是数组的
5. pop(),push(),unshift(),shift()
pop()删除并返回数组最后一个元素
push()向数组末尾添加一个或多个元素,并返回数组新长度
unshift()向数组的开头添加一个或多个元素,并返回数组新长度
shift()删除并返回数组的第一个元素
6. DOM0 DOM2
-
dom0级
不支持添加多个事件,后面的会覆盖前面的
无法取消
var btn = document.getElementById("button");
btn.onclick = function(){
alert(1);
}
btn.onclick = function(){
alert(2);
} //只弹出2
-
dom2
可以添加多个事件
不兼容低版本IE
IE8以及更早版本不支持DOM事件流
event.stopPropagation()阻止事件的进一步传播。
stopImmediatePropagation()不仅阻止事件的传播,还阻止该元素上绑定的其他函数的执行
支持事件冒泡,事件捕获
var btn = document.getElementById("button");
btn.addEventListener("click",function(){
alert("1");
})
btn.addEventListener("click",function(){
alert("2");
}) //先弹出1,再弹出2
w3c标准来说,并没有0级dom的标准。只不过,事实上的适用总会成慢慢成为约定成俗的规
则。所谓的0级dom与2级dom事件就是不同版本间的差异,具体的说就是,对于不同的DOM
级别,如何定义事件处理,以及使用时有什么不同。
DOM0就是直接通过 onclick写在html里面的事件, 比如:
<input onclick="alert(1)" />
DOM2是通过addEventListener绑定的事件, 还有IE下的DOM2事件通过attachEvent绑定;
DOM3是一些新的事件, 区别DOM3和DOM2的方法我感觉是DOM3事件有分大小写的,DOM2没有;
0级DOM
主要分为2个:
一是在标签内写onclick事件
二是在JS写onlicke=function(){}函数
1)
<input id="myButton" type="button" value="Press Me" onclick="alert('thanks');" >
2)
document.getElementById("myButton").onclick = function () {
alert('thanks');
}
-----------------------------------------------------------------------------------------------
2级DOM–(为什么没有1级DOM)
DOM级别1于1998年10月1日成为W3C推荐标准。1级DOM标准中并没有定义事件相关的内容,所以没有所
谓的1级DOM事件模型。在2级DOM中除了定义了一些DOM相关的操作之外还定义了一个事件模型 ,这个标
准下的事件模型就是我们所说的2级DOM事件模型
2级DOM只有一个:
监听方法,有两个方法用来添加和移除事件处理程序:addEventListener()和removeEventListener()。
它们都有三个参数:第一个参数是事件名(如click);
第二个参数是事件处理程序函数;
第三个参数如果是true则表示在捕获阶段调用,为false表示在冒泡阶段调用。
addEventListener():可以为元素添加多个事件处理程序,触发时会按照添加顺序依次调用。
removeEventListener():不能移除匿名添加的函数。
document.getElementById(“myTest”).attachEvent(“onclick”, function(){alert(1)});
//等价于
document.getElementById(“myTest”).addEventListener(“click”, function(){alert(1)}, false);
只有2级DOM包含3个事件:事件捕获阶段、处于目标阶段和事件冒泡阶段
点击a后capturing(捕捉)阶段事件传播会从document-> span->a,然后发生在a,最后bubbling(冒泡)阶段事件传播会从a->span->document 。
1.事件冒泡(常用)
IE中采用的事件流是事件冒泡,先从具体的接收元素,然后逐步向上传播到不具体的元素 。
2.事件捕获(少用)
Netscapte采用事件捕获,先由不具体的元素接收事件,最具体的节点最后才接收到事件。
3.DOM事件流
7. IE和DOM事件流的区别
- 1.执行顺序不一样
事件流的区别
IE采用冒泡型事件 Netscape使用捕获型事件 DOM使用先捕获后冒泡型事件
示例:
<body>
<div>
<button>点击这里</button>
</div>
</body>
冒泡型事件模型: button->div->body (IE事件流)
捕获型事件模型: body->div->button (Netscape事件流)
DOM事件模型: body->div->button->button->div->body (先捕获后冒泡)
-
2.参数不一样 低版本ie没有回调函数,只能进行冒泡
-
3.第一个参数是否加"on",低版本IE不支持addEventListener(),支持attachEvent,第一个参数需要加"on"
element.addEventListener('click', observer, useCapture);
addEventListener方法接受三个参数。第一个参数是事件名称,值得注意的是,这里事件名称与IE
的不同,事件名称是没’on’开头的;第二个参数observer是回调处理函数;第三个参数注明该处理回调
函数是在事件传递过程中的捕获阶段被调用还是冒泡阶段被调用
2.事件侦听函数的区别
IE使用:
[Object].attachEvent("name_of_event_handler", fnHandler); //绑定函数
[Object].detachEvent("name_of_event_handler", fnHandler); //移除绑定
DOM使用:
[Object].addEventListener("name_of_event", fnHandler, bCapture); //绑定函数
[Object].removeEventListener("name_of_event", fnHandler, bCapture); //移除绑定
bCapture参数用于设置事件绑定的阶段,true为捕获阶段,false为冒泡阶段。
- 4.this指向问题,IE指向windows,不指向触发的函数
还有一点要注意的是:元素点击里面的this有问题哦, 在IE8和和IE8以前, 通过attachEvent绑定的事件里面的this是window;
element.attachEvent('onclick', observer);
attachEvent接受两个参数。第一个参数是事件名称,第二个参数observer是回调处理函数。这里得
说明一下,有个经常会出错的地方,IE下利用attachEvent注册的处理函数调用时this指向不再是先
前注册事件的元素,这时的this为window对象了
8. IE标准下有哪些兼容性写法
var ev = ev||window.event//获得event对象兼容性写法
以上第一个ev是变量。
ev是事件的参数!在ev中包含了事件触发时的参数,比如click事件的ev中包含着.e.pageX,e.pageY,
keydown事件中包含着ev.keyCode等,在ie中,ev是全局的可以通过window.event来获取,在其他浏
览器中都是作为参数传入的。
ev储存著事件明细(位置、时间,键盘状态、元素等),以及影响后续的事件流向和结果
(stoppropagation,prevenrdefault 等)
obj.onclick = function(ev) { ...}该事件的回调函数是function(ev),这个ev是用来捕捉事件对象的。
在IE/Opera中,是window.event,而在Firefox中,是event
而事件的对象,在IE中是window.event.srcElement,在Firefox中是event.target,而在Opera中则
两者都支持。
你想像一下, 如果一个键盘事件想对 Enter 和 E 和 Ctrl+Enter 进行不同的处理, 你能怎样知道按下的
是那一个? 靠的就是事件参数了。滑鼠等亦然。
document.documentElement.clientWidth||document.body.clientWidth
1、当文档有了标准声明,IE6在页面内容超出窗口大小时将宽度属性scrollWidth、clientWidth、offsetWidth
都解释为内容实际宽度。比如我们用document.body.clientHeight原本想取得“页面可见区域高度”,可实际上返
回的是“页面实际内容高度”。这时,我们可以用document.documentElement代替document.body来获取我们想要
的结果,将代码中的document.body替换为document.documentElement,再来看看各浏览器下的实际结果:
ii 测试结果表明,IE系列浏览器对document.documentElement属性的解释是正确的,其它标准浏览器将offsetHeight
解释成 了scrollHeight。火狐和netscape更是把这两个属性调换了过来。不过总的来说各属性都可以有个相应的解释。
2、文档有了标准声明时,用document.body.scrollTop会失效,总显示为0,使用document.documentElement.scrollTop
,才会获得正确的值。相反,如果不做标准声明的话,document.documentElement.scrollTop反而会显示为0。
var target = ev.srcElement||ev.target//获得target兼容型写法
IE浏览器支持window.event.srcElement , 而firefox支持window.event.target;
event.srcElement(获得触发事件的元素(IE 浏览器不支持)。)从字面上可以看出来有以下关键字:
事件,源 他的意思就是:当前事件的源, 我们可以调用他的各种属性 就像:document.getElementById("")
这样的功能, 经常有人问 firefox 下的 event.srcElement 怎么用,在此详细说明: [IE]下,event
对象有srcElement属性,但是没有target属性;Firefox下,event对象有target属性,但是没有srcElement
属性.但他们的作用是相当的,即: firefox 下的 event.target = IE 下的 event.srcElement
Event 对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。
文档document,元素element,属性attribute,事件event。
获得需要的文档,元素,属性,然后利用event操控它们。
9. call apply bind
改变this的指向,
call函数的功能就是把当前的this指向作为函数来执行,并且该函数的this指向传入call的参数
call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向。
JavaScript 的一大特点是,函数存在「定义时上下文」和「运行时上下文」以及「上下文是可以改变的」这样的概念。
var Pet = {
words : '...',
speak : function (say) {
console.log(say + ''+ this.words)
}
}
Pet.speak('Speak'); // 结果:Speak...
var Dog = {
words:'Wang'
} //将this的指向改变成了Dog
Pet.speak.call(Dog, 'Speak'); //Pet.speak('Speak')结果: SpeakWang
this 指向所属的对象
这里的this指向必须是引用类型。
如果this被强行改变为值类型,那么能够转为对应包装类型的都会转,不能转的 指向window
设置方法的调用对象(方法的this)时用;
需要注意的是两者传参方式不同:
call():参数直接传入
apply():数组格式传入
其中call的写法
function add(a,b)
{
alert(a+b);
}
function sub(a,b)
{
alert(a-b);
}
add.call(sub,3,1);
这个例子中的意思就是用 add 来替换 sub,add.call(sub,3,1) == add(3,1) ,所以运行结果为:alert(4); // 注意:js 中的函数其实是对象,函数名是对 Function 对象的引用。
apply写法
function add(a,b)
{
alert(a+b);
}
function sub(a,b)
{
alert(a-b);
}
add.apply(sub,[4,2]);
不同就在于第二个参数,apply写成数组
bind写法
function add(a,b)
{
alert(a+b);
}
function sub(a,b)
{
alert(a-b);
}
add.bind(sub,[4,2])();
bind是返回了一个改变上下文的一个函数,可以稍后调用,而apply,call是立即执行函数
call调用apply应用,都是为了使用其他函数或对象的方法,立即执行。bind(绑定,结合)稍后调用。
当你的参数是明确知道数量时用 call 。而不确定的时候用 apply,然后把参数 push 进数组传递进去。
当参数数量不确定时,函数内部也可以通过 arguments 这个数组来遍历所有的参数。
10. b继承a的方法(js面向对象复习)
原型链继承
实现的本质是重写原型对象,代之以一个新类型的实例。
构造函数继承
- 借用构造函数继承
用.call()和.apply()将父类构造函数引入子类函数(在子类函数中做了父类函数的自执行(复制))
实例继承
- 原型式继承
Objcet.create();两个参数:一个用作新对象原型的对象,一个为新对象定义额外属性的对象(可选)。
相当于下面的函数function object(o){
function F(){}
F.prototype = o;
return new F();
}
组合继承
结合了两种模式的优点,传参和复用。
实现的本质:把实例函数都放在原型对象上,以实现函数复用。同时还要保留借用构造函数方式的优点。
(使用原型链实现对原型属性和方法的继承(一般不在原型上写引用属性),而通过借用构造函数来实
现对实例属性的继承)。即在原型上定义方法实现了函数复用,又能保证每个实例都有它自己的属性。
注:组合继承需要修复构造函数的指向。因为重写了原型对象Sub.prototype,这里
Sub.prototype.constructor便指向了构造函数Super,需要修复!!!
拷贝继承
- 寄生式继承
实现的本质: 给原型式继承穿了个马甲而已,看起来比较像继承。同样是基于某个对象或某个信息创建
一个对象,然后增强对象,最后返回对象。
优缺点:
同原型式继承。
寄生组合继承(最优)
function inheritPrototype(subType,superType) {
var prototype = Object(superType.prototype);
prototype.constructor = subType;
subType.prototype = prototype;
}//等于是创建一份superType的原型的副本,为副本添加constructor属性,然后把副本赋值给到subType的原型。而不是像这样SubType.prototype = new SuperType();
//SubType.prototype.constructor = SubType;调用
优点:同组合继承。但解决了组合继承的缺点,只调用了一次父类构造函数,避免了在子类构造函数的
原型上创建不必要的、多余的属性。
缺点:理论上没有。
有缺陷的寄生式继承 + 不完美的组合继承 = 完美的寄生组合式继承
对象冒充
这里存在一个弊端,如果存在两个类 ClassX 和 ClassY 具有同名的属性或方法,ClassY 具有高优先级。因为它从后面的类继承。除这点小问题之外,用对象冒充实现多重继承机制轻而易举。
_proto_指向prototype
用构造方法创建一个新的对象之后,这个对象中默认会有一个不可访问的属性 [[prototype]] (也
就是_proto_), 这个属性就指向了构造方法的原型对象。
在访问属性和方法的时候,查找的顺序是这样的:对象->原型->原型的原型->…->原型链的顶端。
就像一个链条一样,这样由原型连成的”链条”,就是我们经常所说的原型链。
组合模式和动态原型模式是JavaScript中使用比较多的两种创建对象的方式。
建议以后使用动态原型模式。他解决了组合模式的封装不彻底的缺点。
11. 如何阻止事件冒泡和默认事件
cancelBubble(IE),
IE中的方法,和e.stopPropagation()差不多
event.stopPropagation()
event.stopPropagation();可以阻止捕获和冒泡阶段中当前事件的进一步传播。(防止冒泡和捕获)
根据DOM事件的机制,在当前元素上触发的大多数事件都会冒泡传递到该元素的所有祖辈元素上,如果
不在这些祖辈元素上相应的阻止事件,那么在祖辈元素上也会触发这些事件,通过event.stopPropa
gation()的阻止,事件则不会传播到任何的祖辈元素上去。
return false,
javascript的return false只会阻止默认行为,而是用jQuery的话则既阻止默认行为又防止对象冒泡。
event.preventDefault,
event.preventDefault()可以取消默认事件。
同时阻止事件冒泡和默认行为。
可以在事件处理函数中返回false。
这是对事件对象同时调用stopPropagation()方法和preventDefault()方法的一种简写方式。
12. 添加 删除 替换 插入到某个接点的方法
obj.appendChild()
obj.insertBefore()
obj.replace()
obj.remove()
appendChild() 方法向节点添加最后一个子节点。
insertBefore() 方法在您指定的已有子节点之前插入新的子节点。
replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。
* 参数 描述
regexp/substr;必需。规定子字符串或要替换的模式的 RegExp 对象。
请注意,如果该值是一个字符串,则将它作为要检索的直接量文本模式,而不是首先被转换
为 RegExp 对象。
replacement;必需。一个字符串值。规定了替换文本或生成替换文本的函数。
remove() 方法用于从下拉列表select删除选项。
13. window.onload和$(document).ready的区别
20110414211625991.jpgwindow.onload需要等所有文件都加载完才开始加载,$(document).ready只需等文档结构加载完了就开始加载
所以例如图片的高度和宽度这样的属性此时不一定有效。要解决这个问题,可以使用 Jquery 中另一个关于页面加载的方法 ---load() 方法。 Load() 方法会在元素的 onload 事件中绑定一个处理函数。如果处理函数绑定给 window 对象,则会在所有内容 ( 包括窗口、框架、对象和图像等 ) 加载完毕后触发,如果处理函数绑定在元素上,则会在元素的内容加载完毕后触发。
Jquery 代码如下:
$(window).load(function (){
// 编写代码
});等价于 JavaScript 中的以下代码
Window.onload = function (){
// 编写代码
}
14. == 和 === 区别
前者会自动转换类型
后者不会
15. javascript的同源策略(跨域问题)
跨域是什么:实际上就是一个网站不能执行其他网站上的网址,是由浏览器同源策略造成的,是浏览器对js施加的安全限制
所谓同源,实际上是指域名,协议,端口都相同
也就是说当,域名或者协议,或者端口不同的时候,就是跨域,
-
15.1. 解决方法:
jsonp
json with padding,是一种json的一种使用模式
产生的原因,ajax不支持跨域,由于浏览器的同源策略,但是script的src支持跨域
主要的原理是动态创建一个script标签的,通过src调用服务器提供的js脚本,该脚本的内容是一个函数调用,该函数在本地js文件中进行定义,其中的参数就是,本地函数请求的数据,也就是服务器所将返回的数据
与ajax的不同,ajax是通过xhr获取非本页面的数据内容,而jsonp获取的是服务器提供js脚本
代理
例如www.123.com/index.html需要调用
www.456.com/server.php,可以写一个接口
www.123.com/server.php,由这个接口在后端去调用
www.456.com/server.php并拿到返回值,然后再返回给 index.html,这就是一个代理的模式。相当于绕过了浏览器端,自然就不存在跨域问题。
PHP端修改header(XHR2方式)
在php接口脚本中加入以下两句即可:
header('Access-Control-Allow-Origin:*');//允许所有来源访问
header('Access-Control-Allow-Method:POST,GET');//允许访问的方式
16. javascript是一种什么样的语言
解释性脚本语言,代码不进行预编译
主要用来向HTML页面添加交互行为
可以直接嵌入HTML页面,但单独写成js文件,有利于结构和行为的分离
跨平台性,在绝大多数浏览器支持下,可以在多种平台下运行,linux,windows
17. javascript基本数据类型和引用数据类型
基本类型 undefind null number string boolean
基本类型的值是不能改变的
基本类型不能添加属性和方法
基本类型的比较是值的比较
基本类型变量存放在栈区(栈内存)
也就是说基本类型在赋值操作后,两个变量是相互不受影响的。
引用类型 object Function Array
引用类型可以添加属性和方法,属性方法内又可以添加基本类型
引用类型的值是可变的
引用类型的值时同时保存在栈内存和堆内存里的对象,准确地说,引用类型的存储需要内存的栈区和堆区(堆区是指内存里的堆内存)共同完成,栈区内存保存变量标识符和指向堆内存中该对象的指针,
引用类型的比较是引用的比较 引用类型时按引用访问的,换句话说就是比较两个对象的堆内存中的地址是否相同,那很明显,person1和person2在堆内存中地址是不同的
引用类型的赋值其实是对象保存在栈区地址指针的赋值,因此两个变量指向同一个对象,任何的操作都会相互影响
18. js原生不要与jq搞混
document.getELementById("ID").value
获取值的时候原生不是方法,不带括号
获取所有checkbox
var boxs =document.getELementsByTagName("input");
var boxArray = [];
var len = boxs.length;
while(len--){
if(boxs[len].type == 'checkbox'){
boxArray.push(boxs[len]);
}
}
设置div html内容以及设置样式
var dom = document.getElementById("ID");
dom.innerHTML = "xxxx"
dom.style.color="#000"
19. DOM,BOM
javascript由ECMAScript,DOM,BOM三部分组成,
ECMAScript也是一种语言,也就是对规定的语法,操作,关键字,语句等的一个描述,javascript实现了ECMAScript
DOM是文档对象模型,包括了获取元素,修改样式,操作元素三方面内容,也是我们进行最多的操作,有很多兼容性写法
BOM是浏览器对象模型,包括浏览器的一些操作,window.onload,window.open等还有浏览器事件,监听窗口的改变onresize,监听滚动事件onscroll等
20. null和undefind的区别
null是表示一个空的对象,转为数值为0,undefind表示一个空的原始值,转为数值为NAN
undefind指本该有一个值,但却并有定义,null表示没有对象,不应该有值
21. XML和JSON的区别
JSON相对于XML来讲传递速度更快,因为光看代码量就能看出
JSON与js的交互更容易,解析更方便
22. 实现多个标签之间的通信
调用localStorage,cookies等本地存储进行存储相关信息
三者的共同点:都保存在浏览器。
三者的区别:
与服务器的交互
cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。
而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下。
存储大小限制也不同,
cookie数据不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如会话标识。
sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。
数据有效期不同,
sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;
localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;
cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。
作用域不同,
sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;
localStorage 在所有同源窗口中都是共享的;
cookie也是在所有同源窗口中都是共享的。
23. 哪些操作会造成内存泄露
内存泄露指任何对象在不再拥有或不再需要它之后依然存在
setTimeout第一个参数是字符串而不是函数的时候就会造成内存泄露
闭包
控制台日志
循环(两个对象彼此引用且彼此保留)
24. js垃圾回收方式
标记清除:这是js最常用的垃圾回收方法,当一个变量进入执行环境时,例如函数中声明一个变量,将其标记为进入环境,当变量离开环境时,(函数执行结束),标记为离开环境
引用计数: 跟踪记录每个值被引用的次数,声明一个变量,并将引用 类型赋值给这个变量,则这个值的引用次数+1,当变量的值变成了另一个,则这个值的引用次数-1,当值的引用次数为0的时候,就回收
25. 闭包
函数嵌套函数
子级函数调用父级函数的参数或变量
经典闭包
function outer(){
var a = 1;
function inner(){
alert(a);
}
return inner
}
var inn = outer();
inn();
点击li返回li下标
<ul id="test">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
var oUL = document.getElementById("test");
var oLi = oUl.getElementByTagName("li");
for(var i=0;i<oLi.length;i++){
oLi[i].index = i;
oLi[i].onclick = function(){
alert(this.index);
}
}
</script>
<script>
var oUL = document.getElementById("test");
var oLi = oUl.getElementByTagName("li");
for(var i=0;i<oLi.length;i++){
oLi[i].index = i;
oLi[i].onclick = (function(a){
return function(){
alert a;
}
})(i)
}
</script>
26. this指向问题
普通函数调用,指向windows
window.value=1;
function getValue(){
console.log(this.value);
}
getValue();//输出1,此时的this指向window
对象的方法调用,指向对象
var Obj={
value:2,
getValue:function(){
console.log(this.value);//输出2,this指向Obj
}
}
构造器方法调用,指向构造函数实例出来的对象
function main(val){
this.value=val;
}
main.prototype.getValue=function(){
console.log(this.value);
}
var fun=new main(3);
fun.getValue();
fun.value;//输出3,this指向main的实例对象fun
call,apply,bind可以自定义this指向第一个参数
function showValue(){
console.log(this.value);
}
var obj={
value:4
}
showValue.call(obj)//输出4,this指向了obj对象
function showValue(){
console.log(this.value);
}
var obj={
value:4
}
var showValue2=showValue.bind(obj);
showValue2()//输出4,this指向了obj对象
27. 高阶函数
函数作为参数传递,
函数作为返回值输出
28. new操作符到底干了什么
创建一个新对象
将构造函数的作用域赋值给新对象(所以this指向了这个新对象)
执行构造函数的代码(为这个新对象添加属性)
返会新对象
29. js严格模式
"use strict"
消除js一些不合理的用法
消除代码运行的一些不安全之处
增加运行速度
为未来新版本js做铺垫
变量必须声明
对象不能出现重复属性名
arguments改变,不会影响函数参数
eval,arguments变为关键字,不能作为变量名
不允许使用with
不用call,apply,bind改变this指向,一般函数调用指向null
30. 事件代理事件委托
原理是使用dom的冒泡,将事件绑定到父元素上,让父元素进行监听,提高性能
31.什么是版本控制,
版本控制是一种记录一个或若干文件内容变化,以便将来查阅修改以及更新。
32.ajax请求
ajax请求四步
创建一个xhr对象 var xhr = new XmlHttpRequest()
判断就绪状态为4时执行代码
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
console.log(responseText);
}
}
创建请求 xhr.open('get','url',true)
发送请求 xhr.send(null)
33.在浏览器中输入URL到整个页面显示在用户面前时这个过程中到底发生了什么
DNS解析
TCP连接
发送HTTP请求
服务器处理请求并返回HTTP报文
浏览器解析渲染页面
连接结束
详细:
首先根据url中的域名,在远程服务器中查询对应
34.ajax和json
ajax用于web页面中实现异步数据交互,实现页面局部内容刷新
优点:能够进行内容局部加载刷新,减少带宽,避免用户不断刷新以及页面跳转,提高用户体验
缺点:对搜索引擎不友好;浏览器不支持ajax的后退;
json是一种请求轻量级的数据交互格式
优点:轻量级,编译人的阅读理解,便于机器解析
35.http考点
常用的HTTP方法有哪些
GET:
POST:
PUT:
DELETE:
GET与POST方法的区别
get主要是从服务器获取资源,post主要是像服务器发送数据
get传输数据通过url请求,利用k=v的形式放在url后面,用?连接,多个用&连接而post是存放在,ajax中的data中的,get传输的过程使用户可见 的,而post是对用户不可见的。
get传输的数据量小,以为受url的长度限制,但是效率高,post能上传的数据量大
post较get更安全一些
get方式传递的中文字符可能会乱码,post支持标准字符集,可以正确传递中文字符
http请求报文与响应报文格式
请求报文包含三部分:
请求行:包含请求方法、URI、http版本信息
请求首部字段
请求内容实体
响应报文包含三部分:
状态行:包含HTTP版本、状态码、状态码的原因短语
响应首部字段
响应内容实体
http状态码
100-199:成功接收请求,但需要进行下一步请求
200-299:成功接收请求,并完成整个处理过程
300-399:为完成全部请求,客户需近一步细化需求
400-499:客户端请求有错误,包括语法错误或不能正常执行
500-599:服务器端出现错误
http缺点与https
通信使用明文不加密,内容可能被窃听
不验证通信方身份,可能遭到伪装
无法验证报文完整性,可能被篡改
https就是加上加密处理(一般是SSL安全通信线路)+认证+完整性保护
常用:
200 正常,表示一切正常,返会的是正常请求结果
302/307 临时重定向,表示请求的文档,已被临时移动到别处
304 未修改,调用缓存的数据
403 服务器拒绝客户请求
404 服务器不存在客户想要找的资源
500 服务器内部错误
36.数组去重的一种相对好理解的方法
利用indexOf方法的去重
indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。
var arr = [1,1,2,3,4,2,6,4,5,7];
var nArr = [];
function removeItem(arr){
for(var i=0;i<arr.length;i++){
if(nArr.indexOf(arr[i])==-1){
nArr.push(arr[i]);
}
}
return nArr;
}
console.log(removeItem(arr));
es6
let const
let相当于给js新增了块级作用域,声明的变量只在let命令所在的代码块内有效
const也是声明变量,它声明的变量,不能改变,可以用来声明第三方库变量的应用
class extends super
class定义一个类,其中有一个construct方法,construct方法中的this代表实例对象,construct以外还有其他的方法,construct内定义的方法属性是实例对象自己的,construct外的方法属性是所有实例对象共享的
class之间可以通过extends实现继承
super指代父类的实例,子类construct中必须先调用super()方法,因为子类没有自己的this对象,是继承父类的this对象
arrow function(箭头函数)
除了书写简洁了很多,最大的优点是this指向,使用箭头函数,函数内部的this就是定义时所在的对象。箭头函数根本没有自己的this,this是继承外面的,它内部的this就是外层代码块的this
template string(模板字符串)
ajax调用数据库,需要向文档中插入大段html的时候,传统的字符串拼接太麻烦,引入模板工具库会稍微好点,不过还是没有es6的template string简单,可以直接用反单引号包括代码块``,用${}来引用变量,所有的空格缩进都会保留到输出中
destructuring(解构赋值)
es6按照一定模式,从数组和对象中提取值,对变量进行赋值,这就成为解构,也就是说,运用es5的方法,数组和对象中的变量需要,一个个进行赋值,而es6可以一步到位
default,rest(默认值,扩展语法)
当函数忘记传参的时候,给它一个默认值,传统方法是在函数中运用||,es6可以直接在参数中写上
function animal(type){
type = type || 'cat'
console.log(type)
}
animal()
function animal(type = 'cat'){
console.log(type)
}
animal()
function animals(...types){
console.log(types)
}
animals('cat', 'dog', 'fish') //["cat", "dog", "fish"]
gulp
gulp是一种自动化构建工具,前端工程化开发的一种工具,增强开发流程
使用方便,npm安装,新建gulpfile.js,导入gulp模块,let gulp = require('gulp')
通过default任务去定义工作流
最后在终端执行gulp来进行自动化操作
api很简单只有四种
gulp.task 创建任务 :参数任务名称,前置任务数组,回调函数
gulp.src 寻找文件:通过路径找到一个或多个文件
gulp.dest 输出到指定目录:如果没有就新建一个
gulp.watch 监听文件变化,执行任务
pipe具体不清楚,总之,除了gulp.src之外,其他执行条件都要放在.pipe()中
Bootstrap
Bootstrap和Foundation的比较
UI元素的不同
Bootstrap给出了能想到的一切元素,也就是试图提供所有定义好的UI,比如一个导航,给予一个默认导航的样式
Foundation只给定了限定的几种元素,可以自己自定义,更适合创造
尺寸单位不一样,
Bootstrap是px
Foundation是rem
网格布局有所不同
Foundation 的网格可以自动适配当前浏览器的宽度,Foundation 则会灵活适配当前的浏览器宽度, 这是一种新的技术手段, 自动适配的同时, 可以表现的与 Transformer 一样的效果.
Boostrap 则是预定义了几种网格尺寸来适配主流的设备和屏幕.Bootstrap 会在你改变浏览器宽度的时候突然改变它的网格.
移动设备
Foundation移动设备优先
Bootstrap也支持移动设备
社区
Bootstrap有一个完备的社区,有什么问题几乎都可以迅速解决
Foundation则没有,需要自力更生