前面的话
做了两套网易的题,正式篇觉得还好,提前批的题目虽考点差不多,但有很多坑,同时也考得比较深。
题目
第一题: 下面代码输出什么?
const arr = [];
const testObj = {};
console.log(arr === "");
console.log(arr == "");
arr.toString = () => 1;
console.log(arr === 1);
console.log(arr == 1);
arr.valueOf = () => 2;
console.log(arr == 2);
arr.valueOf = () => testObj;
console.log(arr == testObj);
考查:valueOf()与toString()方法的调用
在两者没有重写的情况下,默认调用toString()方法。在两者都存在时,如果是数值运算优先调用valueOf()方法。注意:不能使用toString()与valueOf()方法返回对象
console.log(arr === "")
false ===比较类型console.log(arr == "")
true 调用toString()方法console.log(arr === 1)
false ===比较类型。console.log(arr == 1)
true 调用toString()方法console.log(arr == 2)
true 两者并存,数值运算优先调用valueOfconsole.log(arr == 1)
true 本应使用valueOf()方法,但是valueOf返回的是一个对象,所以不使用valueOf()方法,使用toString()方法console.log(arr == testObj)
flase 这里调用toString()方法,arr应该等于1.
第二题:下面代码输出什么?
let a = 0;
const obj = {
a: 1,
b: function() {
console.log(this.a);
}
}
const obj1 = {
a: 2
}
const fun = obj.b;
fun();
fun.apply(obj);
fun.bind(obj1).apply(obj);
const fun1 = fun.bind(obj1);
fun1();
new fun();
- fun()是普通函数调用,this指向window,但是全局的a使用let声明,不是属于window对象,使用let与const声明的变量都不在window上。所以这里打印undefined
- fun.apply(obj);将this指向了obj,这个简单,打印1
- fun.bind(obj1).apply(obj)这个使用bind函数改变this指向,注意bind 与call和apply函数不一样的地方就是,它返回一个绑定函数,这个绑定函数确定了this以及形参,不能再被改变。所以this指向为obj1,后面再调用apply也无法改变。打印2
- fun1(): fun.bind(obj1)与上面一个改变this指向为obj1,返回2.
- new fun();这个考new一个过程发生了什么?
1、新生成了一个对象
2、获得构造函数
3、链接到原型
4、绑定 this,执行构造函数
5、返回新对象
这里就会执行构造函数,而这个构造函数没有a属性,所以返回undefined。如果在构造函数里面加一个this.a = 9,就会打印9.
第三题: Function.prototype的原型链最终指向的哪?
这题考查的是Function与Object的鸡蛋问题。
-
我们都知道每个对象都有__proto__对象,并且对象的原型链终端等于null。
obj.__proto__.__proto__ .......__proto__ === null
也就是说:Object.prototype.__proto__ === null
-
但是函数也是对象,JavaScript里面定义了一个特殊的函数Function,这是所有函数的爸爸,所以函数都是它的实例。例如:
var fun = function() {}; console.log(fun.__proto__=== Function.prototype);// true
这里的Function.prototype也是一个特殊的对象,在控制台里面打印这个对象,是这样的,什么也没有:
但Function.prototype还是有原型,指向Object.prototype,最终有:console.log(Function.prototype.__proto__ == Object.prototype);// true
-
那么Function呢?Function也是一个函数,也是对象,它的__proto__指向谁?是它自己,即:
console.log(Function.__proto__ === Function.prototype);// true console.log(Function.prototype === Function.prototype);// true Function instanceof Function === true; Function.__proto__.__proto__ === Object.prototype; Function instanceof Object === true;
-
Function 与Object的关系(鸡蛋问题)
一般对象的都是Object的instance,因为原型链的顶端都指向Object.prototype。而Object也是个函数,而任何函数都是Function的实例对象,比如Array,String,当然Object也在内,即:console.log(Object.__proto__ === Function.prototype);// true console.log(Object instanceof Function === true);// true
而同时,Function又是一个对象,它的原型
Function.__proto__
指向 Function.prototype,并且这个原型链向上继续指向Object.prototype,即:console.log(Function.__proto__.__proto__ == Object.prototype);// true console.log(Function.prototype.__proto__ == Object.prototype);// true console.log(Function instanceof Object === true);// true
到这里就出现了鸡蛋问题:
console.log(Function instanceof Object === true);// true console.log(Object.__proto__ === Function.prototype);// true
至于谁先谁后,网上已经有很多解释了,这里不多说了,回到本题,Function.prototype的原型链的终端指向: null
console.log(Function.prototype.__proto__=== Object.prototype);// true console.log(Function.prototype.__proto__.__proto__ == null);// true
第四题:
<canvas width="250" height="250"></canvas>
有个矩形长20px,高10px,CSS中width:250px height:500px,请问这个矩形渲染出来的实际面积(A)?
A.400 B.200 C.300 D.800
解析:
画布大小和CSS中设置width:250px height:500px一致,其width和初始值比例为1:1,height和初始值比例为2:1。因此渲染出来的矩形的高度也将扩大一倍为20px,则矩形渲染出来的实际面积20X20=400。
第五题
下列布局在页面上的宽度比是多少?
.flex {
display: flex;
width: 200px;
height: 100px;
}
.left {
flex: 3 0 50px;
background: red;
}
.right {
flex: 2 0 100px;
background: blue;
}
// html
<div class="flex">
<div class="left"></div>
<div class="right"></div>
</div>
解析: 本题考查flex计算规则
属性值:
flex-grow: 定义项目的放大比例,默认为0
flex-shrink: 定义项目的缩小比例,默认为1
flex-basis: 定义了在分配多余空间之前,项目占据的主轴空间(main size),默认为auto
flex: 是flex-grow,flex-shrink和flex-basis的简写
- flex-grow:分配剩余的空间
- flex-basis(盒子的基准值):可以代替声明width属性,同时声明width属性和flex-basis属性时,会以flex-basis的值来计算。
- flex-shink: 当子盒子的flex-basis或者width之和 > 容器的padding的左边界到padding的右边界时,根据flex-shink值来缩小子盒子的空间. 比如:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test</title>
<style>
.container {
display: flex;
width: 200px;
height: 400px;
border: 1px solid #c3c3c3;
}
.first {
flex-basis: 40px;
flex-shrink: 1;
background-color: red;
}
.second {
flex-shrink: 3;
background-color: blue;
width: 200px;
}
.third {
flex-basis: 40px;
flex-shrink: 2;
background-color: yellow;
}
</style>
</head>
<body>
<div class='container'>
<div class='first'></div>
<div class='second'></div>
<div class='third'></div>
</div>
</body>
</html>
上面代码, 父容器定义宽度200px,因为flex-basis可替代width属性的。
所以,子盒子宽度为 (200+40+40)= 280px,溢出了80px。
首先计算加上权重的值:1*40 + 3 * 200 + 2 * 40 = 720 px
.first 需要缩小的值:(40 * 1/720) * 80 = 4.44px
.second 需要缩小的值:(200 * 3/720) * 80 = 66.67px
.first 需要缩小的值:(40 * 2/720) * 80 = 8.89px
回到本题:left与right盒子基准值为50px、100px。父盒子的宽度剩余50px,剩下的50px 按照
flex-grow的值来分配,这里left盒子为50+50*3/5 = 80px
, right盒子为100+50*2/5px =120px
所以最终为80px: 120px = 2 : 3