1、
var a = 100;
function fn() {
alert(a);
var a = 200;
alert(a);
}
fn();//undefined 200
alert(a);//100
var a;//没有求改window.a的值
alert(a);//100
var a = 300;
alert(a);//300
考点1:scope作用域,var定义的变量提前在器作用域的最顶端进行声明,函数中的第一处调用输出的是undefined.
2、
var obj1 = {name: 'obj1', fn: function() {
document.write(this.name);
}};
var obj2 = {name: 'obj2'};
var obj3 = {name: 'obj3'};
obj1.fn();//this指向obj1 àobj1
var newFn = obj1.fn;//newFn为一个普通方法
newFn();//window下的方法,this指向window,->””
newFn.call(obj2);//利用call使this指向obj2,->obj2
obj3.fn = newFn;
obj3.fn();//this指向obj3 –>obj3
考点:this的指向,this总是指向调用该方法的对象(普通变量和方法均是挂在window上的,在非严格模式下)。在非严格模式下this默认指向是window ,在window上如果调用没有定义的属性则会返回””;普通对象下引用没有过定义的对象则返回值是undefined,在引用的时候进行声明但没有初始化。引用普通未声明的变量则报错。
3、
var obj = {};
obj.log = console.log;
obj.log.call(console,this);
解析:相当于调用的是console.log(this),所以this——》为window
4、ajax中的事件有:
ajaxComplete(callback)
ajaxError(callback)
ajaxSend(callback)
ajaxStart(callback)
ajaxStop(callback)
ajaxSuccess(callback)
5、JS中的数据:
基本数据类型:Number,String,Boolean,Undefined,Null
复杂数据类型:Object,Array,Function,RegExp,Date,Error
全局数据类型:Math
6、void是一元运算符,void 作为运算符后面接的是表达式,void expression。而void(0)也是被当做void 0。如果直接void(),那么我觉得应该是把void当做函数使用了,但是此时void并没有定义。
7、
输出答案:4400 4401 4399 4400
两个不同对象的闭包是彼此独立的,不互相影响。
var result=test(); //执行test返回{n:4399,add:add};
var result2=test(); //同理
result.add(); //test构成闭包,add作用域链包含test活动对象,所以n++,会调用test活动对象的n累加,得到4400
result.add(); //同理
console.log(result.n); //这个n不是test活动对象里面的n
result2.add(); //同理,作用域链有test活动对象,但是这个跟result的不是同一个。
8、console.log('Value is ' + (val != '0') ? 'define' : 'undefine');
加号的优先级高于三目运算符,答案为:define
9、
var f=function g(){
return 23;
};
typeof g();
如果是typeof f,结果是function
如果是typeof f(),结果是number
如果是typeof g,结果是undefined.
如果是typeof g(),结果是ReferenceError,g is not defined
10、下列说法正确的是()
display: none;不为被隐藏的对象保留其物理空间;
visibility:hidden;所占据的空间位置仍然存在,仅为视觉上的完全透明;
visibility:hidden;产生reflow和repaint(回流与重绘);
visibility:hidden;与display: none;两者没有本质上的区别;
解析:
display: none和visibility:hidden的区别就是visibility:hidden会保留元素的空间
repaint(重绘) ,repaint发生更改时,元素的外观被改变,且在没有改变布局的情况下发生,如改变outline,visibility,background color,不会影响到dom结构渲染。
reflow(渲染),与repaint区别就是他会影响到dom的结构渲染,同时他会触发repaint,他会改变他本身与所有父辈元素(祖先),这种开销是非常昂贵的,导致性能下降是必然的,页面元素越多效果越明显。
所以display:none才会产生reflow
visibility:hidden只会出发repaint
11、给定下面的 HTML 代码:
<div id=”wrapper”>
<div class=”wText”>…</div>…<!—more wText items here -->
<div class=”wImg”>…</div>…<!—more wImg items here -->
<div class=”wVideo”>…</div>…<!—more wVideo items here -->
</div>
怎么能够取得 ”wrapper” 中全部项的集合?
A:$(‘#wrapper’).children();
B:$(‘#wrapper’).html();
C:$(‘#wrapper’).contents();
D:$(‘#wrapper’).find(“all”);
解析:A中获取的是子元素而不会获取子元素的子元素
B用于获取文档结构获取的不是对象
C获取子元素以及子元素的子节点,包括所有的文本和注释
D jQuery中用于获取筛选指定的元素的方法
12.以下代码的输出结果:
var a=new Array();
a[0]=1;
a[1]=2;
a.foo="12";
a.length
数组也是对象,可以为其添加或者是删除属性,但是数组本身的长度任然还是与数字属性相关长度
13、变量作用域链(其是在变量定义的是就产生了)中查找的要注意的几个特例:
(1)函数定义在外部函数的外面,只是在内部进行调用时:
var x = 10;
function foo() {
alert(x);
}
function b() {
var x = 20;
foo(); // 10, but not 20
};
b();
(function (funArg) {
var z = 30;
funArg();
})(foo)//输出的仍然是10
解析:方法foo定义在b函数的外面,定义时scope作用域链就已经创建了,在调用时将使用的是全局变量而非局部变量,foo是挂在Window的对象上的,处于顶级作用域,执行时使用的应该是全局的变量和其自身的定义的局部变量。如果说方法foo的定义在b里面则情况scope中将会包含有b中定义的变量。
(2)对象上的方法当重新赋值时会导致执行的上下文对象变化:
var a=12
var obj={
a:23,
foo:function(){
console.log(this.a);
}
}
Var b=obj.foo;//b将挂在window上执行时,this为window
Obj.foo() //23;
b()//输出12
b.call(obj)//23,通过call改变this的指向
(3)利用new Function构造的函数不能使用当前局部作用域内的变量:
var x = 10;
function foo() {
var y = 20;
var barFn = Function('alert(x); alert(y);');
barFn(); // 10, "y" is not defined
}
foo();
(4)with创建的作用域的优先级是最高的,在变量的查找过程中
var x = 10, y = 10;
with ({x: 20}) {
var x = 30, y = 30;
alert(x); // 30改变的是当前的对象的值
alert(y); // 30//当前作用域中不存在y改变时全局变量的值
}
alert(x); // 10
alert(y); // 30
在with作用域中首先在当前作用域变量中查找是否有相关的变量,如果有则使用当前作用域中的变量,没有则在对象的属性中进行查找,如果还没有找到则到上一层作用域中查找,沿着作用域链进行查找。同时在with中定义的新变量则属于上一级作用域。
14、通过这种方式也可以是实现对象的继承,对象继承的方式有三种:
(1) 利用object.create(prototype);
(2) 利用obj.setPrototype();
(3) 利用构造函数调用的方式:
function a(x,y){
this.a=x;
this.b=y;
}
function b(){
a.call(this,x,y);
}
通过构造函数b构造的对象将继承a的属性a,b
15、置换元素
内联元素通常是不能进行宽高的设置的但是有一类内联元素置换元素,其本身就具有指定的宽或高,同时也可以对其宽或高进行设置,img标签本身就具有宽高,当设置宽度时,高度会根据给定的比例进行调整。还有类似的置换元素:input /textarea/select/img/button/label
16、不稳定的排序方法:
(1)快速排序
(2)堆排序
(3)选择排序
(4)希尔排序
17、window.history(会保存用户在一个会话期间的网站访问记录)的几个方法:
(1)back()、go()、forward()可以改变网站的浏览器url的状态,同时如果调用这几个方法的话会触发事件popState,子啊浏览器中点击相关的按钮也会触发该事件window.history.length可以返回历史浏览列表中的url的个数。
(2)H5中新增的方法:
pushState(state,title,url),将某个浏览的url保存到history中,但是不会触发事件popstate
replaceState(state,title,url),将指定的url替换当前的url但是也不会触发popstate事件
state对象 –state对象是一个JavaScript对象,它关系到由pushState()方法创建出来的新的history实体。用以存储关于你所要插入到历史 记录的条目的相关信息。State对象可以是任何Json字符串。因为firefox会使用用户的硬盘来存取state对象,这个对象的最大存储空间为640k。如果大于这个数 值,则pushState()方法会抛出一个异常。如果确实需要更多的空间来存储,请使用本地存储。
title—firefox现在回忽略这个参数,虽然它可能将来会被使用上。而现在最安全的使用方式是传一个空字符串,以防止将来的修改。或者可以传一个简短的标题来表示state
URL—这个参数用来传递新的history实体的URL,注意浏览器将不会在调用pushState()方法后加载这个URL。但也许会过一会尝试加载这个URL。比如在用户重启了浏览器后,新的url可以不是绝对路径。如果是相对路径,那么它会相对于现有的url。新的url必须和现有的url同域,否则pushState()将抛出异常。这个参数是选填的,如果为空,则会被置为document当前的url。
上面的两个方法只是改变了history的实体的是不会刷新页面
(3)可以通过浏览器的事件popstate以及上诉两个新增的方法+ajax实现局部刷新改变页面的内容同时改变url地址,不过需要服务器端的配合
18、[1,2,3].map(parseInt)返回的值是什么?
解答:返回值是[1,NaN,NaN],这个题主要考的是map中方法的参数和parseInt 中的参数的关系,在map中的方法有三个参数,val,index ,arr(数组本身)。在parseInt中的参数str,radix。Str指的是待转换的字符串,radix指的是数字2-36之间的整型,默认值是10进制。所以map返回的三个参数的前两个对应了str和radix当radix的范围超出2-36时会返回NaN。数组传进去后的情况相当于下面的情形:
parseInt('1', 0); //返回1,如果第二个参数是0则会当做十进制处理
parseInt('2', 1); //返回NaN
parseInt('3', 2); //返回NaN
19、
var name = 'World!';
(function () {
if (typeof name === 'undefined') {
var name = 'Jack';
console.log('Goodbye ' + name);
} else {
console.log('Hello ' + name);
}
})();
解析:输出结果为Goodbye Jack,这个题目主要是考察的变量的声明的提升以及变量的作用域问题。闭包中变量声明会被提升,但是初始化不会,因而不会使用全局变量,但是在变量初始化之前进行调用为undefined。
20、
var END = Math.pow(2, 53);
var START = END - 100;
var count = 0;
for (var i = START; i <= END; i++) {
count++;
}
console.log(count);
解析:这段代码会进入死循环, 2^53 是javascript中最大的数字, 2^53+1 与 2^53 等同, 因此 i 永远也不会比这个数大。当JS中的数值最大的表示范围-2^53-2^53时,小范围内的改变值的大小时不会有影响,因为JS的精度已经丢失。如上面的,达到最大之后,值的大小不大发生变化。:
var a = 111111111111111110000,
b = 1111;
a + b;
由上知该题的结果应该是111111111111111110000,因为a的大小已经超过了最大的表示范围。
21、
var two = 0.2
var one = 0.1
var eight = 0.8
var six = 0.6
[two - one == one, eight - six == two]
解析上面的返回结果为[true,false],这跟JS中浮点数的精度有关,在进行运算是均是将十进制转换为二进制进行运算后再将结果转换为十进制。有时候看上去是没有问题的但是有时候会有问题。最好将器装换为十进制后在进行计算。
22、
function showCase(value) {
switch(value) {
case 'A':
console.log('Case A');
break;
case 'B':
console.log('Case B');
break;
case undefined:
console.log('undefined');
break;
default:
console.log('Do not know!');
}
}
showCase(new String('A'));
function showCase2(value) {
switch(value) {
case 'A':
console.log('Case A');
break;
case 'B':
console.log('Case B');
break;
case undefined:
console.log('undefined');
break;
default:
console.log('Do not know!');
}
}
showCase(String('A'));
解析:switch 使用的是全等(===)来进行操作的,利用new String()构造函数实例化的是Object和字面量是不相等的,但是如果没有new则String(“A”)===“A”
23、
function sidEffecting(ary) {
ary[0] = ary[2];
}
function bar(a,b,c) {
c = 10
sidEffecting(arguments);
return a + b + c;
}
bar(1,1,1)
解析:arguments 中的值是随着函数的参数一起变化的,当argument[]通过角标的形式修改参数时,则参数的值约会发生改变。如:
function doAdd(num1,num2){
arguments[1] = 10;
alert(arguments[0] + num2);
}
doAdd(1,2) // alert(11)
同时arguments是个类数组对象,传递引用,当在函数中发生改变时,同时也修改了arguments的值。所以上面题目的答案是21
24、3.toString()
3..toString()
3...toString()
解析:返回结果是error,3,error 。在调用方法时,一般会先进行对象包装,先将其包装为对象,然后代用对象上的方法,调用完后恢复。第一种情形中无法确认类型,因而不能封装为对象,所以会报错。第二种是number类型,可以封装后调用number的方法。
25、如何实现是实现浏览器多tab之间的通信?
解析:
(1)利用本地存储:localstorage,当在一个浏览器页面中修改,添加或者删除了其值时,会触发storage事件,在其他的页面对该事件进行监听即可以实现通信:
window.addEventListener("storage",function(event){
$("#name").val(event.key+”=”+event.newValue);
});
(2)利用cookie+setInterval,轮询的方式
(4) 借助服务器:websocket