1.以下程序执行后返回的结果是:( )
var p1 = {
name:'小明',
age:'12',
action:function(where,doing){
console.log(this.age + '岁的'+this.name + '在' + where + doing);
}
}
var p2 = {
name:'小红',
age:'15'
}
console.log(p1.action.call(p2,'操场上','运动'))
解答:15岁的小红在操场上运动
2.写出程序运行的结果
var k = 0;
for(var i=0,j=0;i<10,j<6;i++,j++){
k += i + j;
}
console.log(k);
//---分割---
var k = 0;
for(var i=0,j=0;j<6,i<10;i++,j++){
k += i + j;
}
console.log(k);
解答:30、90
说明:逗号表达式只有最后一项是有效的,for循环中最后一个布尔值判断决定了循环是否继续
3.以下代码执行后,console 的输出是?
let x = 10;
let foo = () => {
console.log(x);
let x = 20;
x++;
}
foo();
解答:抛出 ReferenceError
说明:只要块级作用域内存在let命令,它所声明的变量就"绑定"了这个区域,不再受外部的影响,在语法上,称为"暂时性死区"。
4.打印值
console.log(Number("")); //0
console.log(Number(null)); //0
console.log(Number(undefined)); //NaN
console.log(Number([])); //0
console.log(Number()); //0
console.log(Number([0])); //0
console.log(parseInt("")); //NaN
console.log(parseInt(null)); //NaN
console.log(parseInt(undefined)); //NaN
console.log(null == 0); //false
console.log(undefined == 0); //false
document.write(new Boolean());
document.write(new Boolean(0));
document.write(new Boolean(null));
document.write(new Boolean(""));
document.write(new Boolean(NaN));
console.log(([])?true:false);
console.log(([]==false?true:false));
console.log(({}==false)?true:false);
5.浮点数精度问题
与其他 IEEE 754 表示浮点数的编程语言一样,JavaScript 的 number 存在精度问题,比如 0.2 + 0.4 的结果是 0.6000000000000001。以下选项中,能得到 0.6 的是?
- parseFloat(0.2 + 0.4)
- parseFloat((0.2 + 0.4).toFixed(1))
- Math.round(0.2 + 0.4)
- parseFloat((0.2 + 0.6).toPrecision(1))
解答:parseFloat((0.2 + 0.4).toFixed(1))
说明:
parseFloat 解析一个字符串,并返回一个浮点数
toFixed 把数字转换为字符串,结果的小数点后有指定位数的数字
Math.round 把一个数字舍入为最接近的整数
toPrecision 把数字格式化为指定的长度
6.打印输出
function out(x){
var temp = 2;
function inside(y){
document.write( x + y + (temp--));
}
inside(5);
}
out(3);
解答:10
说明:
运算符前置和后置的区别:如果该运算符作为后置操作符,则返回它递减之前的值。 如果该运算符作为前置操作符,则返回它递减之后的值。
后置:
var i = 5;
var a = i–;
console.log(i);//输出4
console.log(a);//输出5
前置:
var j = 5;
var b = --j;
console.log(j);//输出4
console.log(b);//输出4
7.输出打印值
var obj = {};
obj.log = console.log;
obj.log.call(console,this);
解答:window
说明:
这道题看似在考this的绑定问题,实际上是通过this绑定为幌子,考察非严格模式下JavaScript语句中“this”默认指向全局对象(window)。
题目的关键点在第3行,我们知道,this绑定的优先级是new>bind>call(apply)>obj.func()>默认绑定。也就是说obj.log.call(console, this)语句中,实际上log函数内的this实际上指代的是console(这也是本题最大的陷阱!)。然而实际上这一语句中obj.log.call(console, this)这一语句中打印的this是在外部传进去的,和函数内的this对象根本没有关系!也就是说此时log函数内的this指代console,但是打印的是从外面传进去的this对象,也就是window!
为了证明这一点,读者朋友们可以把obj.log.call(console, this)中的console改成任意一个对象,然后在非严格模式下执行,会发现结果都是window。
8.位运算,输出打印值
//假设有如下代码,那么a(10)的返回结果是?( )
function a(a)
{
a^=(1<<4)-1;
return a;
}
解答:5
说明:1<<4,转换二进制左移4未,未10000,转成十进制未16,16-1得到15;a = a^15,
a = 10 ^ 15;转化为二进制a = 1010^1111;得到 a = 0101;转换为10进制得到5。
9.排序问题,求array的结果
var array=[-1,1,3,4,6,10];
array.sort((a,b)=>Math.abs(a-3)-Math.abs(b-3));
解答:[3,4,1,6,-1,10]
说明:按照数据元素-3的绝对值,从小到大进行排序(Array.prototype.sort里面传入函数,对于函数返回值大于0,调换顺序,小于等于0顺序不动。)
10.JS类型判断,alert结果为
var x = new Boolean(false);
if (x) {
alert('hi');
}
var y = Boolean(0);
if (y) {
alert('hello');
}
解答:hi,
说明: if(x) 这里期望 x 是一个布尔类型的原始值,而 x 是一个对象,任何对象转为布尔值,都为得到 true(在 JS 中,只有 0,false,NaN,"",null,undefined 这六个值转布尔值时,结果为 false)
题目的第二部分,一定要注意 y = Boolean(0),而不是 y = new Boolean(0)。这两个有很大区别,用 new 调用构造函数会新建一个布尔对象,此处没有加 new,进行的是显示类型转换,正如上述第一条所说,0 转换布尔,结果为 false,所以此时 y 的值就是 false。如果加了 new,那么 y 就是一个 Boolean 类型的对象,执行 if(y) 时,对象转布尔,始终是 true,所以结果会与不加 new 的时候相反。
11.在大数据量场景下,以下哪种js中字符串连接方式较为高效
- a+=b
- a = a+b
- Array.join()
- Array.push()
解答:3
说明:+的处理机制是:新建一个临时字符串,将新字符串赋值为a+b,然后返回这个临新字符串并同时销毁原始字符串,所以字符串连接效率较低。所以用Array.join()不会新建临时字符串效率更高。
13.以下表达式不会出现错误的有
- 2.toString()
- 2…toString()
- 2 .toString()
- (2).toString()
解答:2,3,4
说明:数字后面.会被解析为小数点,而2、3、4则规避了这种情况。
14.请选出3的颜色
<style>
ul { color: blue !important; }
ul > li { color: green; }
ul li + li { color: red; }
li { color: yellow; }
</style>
<ul><li>1</li><li>2</li><li>3</li></ul>
解答:红色
说明:优先级计算
一个选择器的优先级可以说是由四个部分相加 (分量),可以认为是个十百千 — 四位数的四个位数:
千位: 如果声明在 style 的属性(内联样式)则该位得一分。这样的声明没有选择器,所以它得分总是1000。
百位: 选择器中包含ID选择器则该位得一分。
十位: 选择器中包含类选择器、属性选择器或者伪类则该位得一分。
个位:选择器中包含元素(类型)、伪元素选择器则该位得一分。
通用选择器 (*),组合符 (+, >, ~, ’ '),和否定伪类 (:not) 不会影响优先级。
继承的属性优先级为0
15.以下代码执行的结果是:
function fun() {
return () => {
return () => {
return () => {
console.log(this.name)
}
}
}
}
var f = fun.call({
name: 'foo'
})
var t1 = f.call({
name: 'bar'
})()()
var t2 = f().call({
name: 'baz'
})()
var t3 = f()().call({
name: 'qux'
})
解答:foo foo foo
说明:箭头函数没有自己的this,this的指向只有一个,就是函数fun的this
箭头函数有几个使用注意点:
(1)箭头函数没有自己的this对象(详见下文)。
(2)不可以当作构造函数,也就是说,不可以对箭头函数使用new命令,否则会抛出一个错误。
(3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
(4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
16.关于cookie和session
17.关于HTTP和HTTPS协议
18.重绘和回流
19.浏览器渲染流程,以下哪个顺序是正确的?
1、构建render树
2、绘制render树
3、布局render树
4、解析HTML并构建DOM树
解答:4 1 3 2
说明:浏览器渲染原理及流程
20.求打印值
var name = "window";
function showName() {
console.log(this.name);
}
var person1 = {
name: "kxy",
sayName: showName
}
var person2 = {
name: "Jake",
sayName: function() {
var fun = person1.sayName;
fun();
}
}
person1.sayName();
person2.sayName();
解答:kxy、window
说明:this有四种情况
1)当在函数调用的时候指向window
2)当方法调用的时候指向调用对象
3)当用apply和call上下文调用的时候指向传入的第一个参数
4)构造函数调用指向实例对象
21.请给出这段代码的运行结果
var bb = 1;
function aa(bb) {
bb = 2;
alert(bb);
};
aa(bb);
alert(bb);
//-----------------
var name="global";
if(true){
var name="local";
console.log(name)
}
console.log(name);
解答:2,1/ local ,local
说明:待补充
22.下面这个JS程序的输出是什么
function Foo() {
var i = 0;
return function() {
console.log(i++);
}
}
var f1 = Foo(),
f2 = Foo();
f1();
f1();
f2();
解答:0 1 0
说明:一般来说函数执行完后它的局部变量就会随着函数调用结束被销毁,但是此题foo函数返回了一个匿名函数的引用(即一个闭包),它可以访问到foo()被调用产生的环境,而局部变量i一直处在这个环境中,只要一个环境有可能被访问到,它就不会被销毁,所以说闭包有延续变量作用域的功能。
foo()返回的是一个匿名函数,所以f1,f2相当于指向了两个不同的函数对象
22.在浏览器控制台执行以下代码,输入的结果是
function test(){
var n = 4399;
function add(){
n++;
console.log(n);
}
return {
n: n,
add: add
}
}
var result = test();
var result2 = test();
result.add();
result.add();
console.log(result.n);
result2.add();
解答:4400 4401 4399 4400
说明:图片
23.写出打印值
(function() {
var x=foo();
var foo=function foo() {
return "foobar"
};
return x;
})();
(function() {
var x=foo();
function foo() {
return "foobar"
};
return x;
})();
解答:TypeError: foo is not a function、foobar
说明:1.foo变量声明提前了,但是赋值没有提前。2.函数提升
24.求y,z的运行结果
var m= 1, j = k = 0;
function add(n) {
return n = n+1;
}
y = add(m);
function add(n) {
return n = n + 3;
}
z = add(m);
解答:4,4
说明:在js中,定义了两个同名函数后,后面的函数会覆盖前面定义的函数。结合这道题来说,由于函数声明提升,所以函数声明会提前,由于存在同名函数,后面的add函数将覆盖第一个add函数,所以两次调用add()返回的值是相同的。也就是y,z都为4
引申:
function f(){return 1;}
alert(f());
var f = new Function("return 2;");
alert(f());
var f = function(){return 3;}
alert(f());
function f(){return 4;}
alert(f());
var f = new Function("return 5");
alert(f());
var f = function(){return 6 ;}
alert(f());
25.求打印值
function bar(x = y, y = 2) {
return [x, y];
}
bar();
解答:报错 y is not defined
说明:暂时性死区,调用bar函数之所以报错(某些实现可能不报错),是因为参数x默认值等于另一个参数y,而此时y还没有声明,属于“死区”。如果y的默认值是x,就不会报错,因为此时x已经声明了。