目录
1、arguments类数组转化为数组,[].slice.call()与Array.prototype.slice.call(),为什么不可以用Array.prototype?
8、forEach方法中 无法通过return break终止循环
1、arguments类数组转化为数组,[].slice.call()与Array.prototype.slice.call(),为什么不可以用Array.prototype?
[]和Array.prototype上都有slice方法,Array没有,他是一个构造方法。
slice方法中遍历类数组,并push进新建数组,最后返回新数组
也可以手动实现转换
Object.prototype.toArray = function () {
console.log('toArray', this)
if ((typeof this === 'object') && this != null &&
Object.prototype.hasOwnProperty.call(this, 'length')) {
let arr = [];
for (let i = 0; i < this.length; i ++) {
arr.push(this[i]);
}
return arr;
} else {
return [];
}
}
let obj = {
0: 'param1',
1: 'param2',
2: 'param3',
length: 3,
push: function() {
this[length] = arguments[0];
this.length ++;
}
}
let arr = obj.toArray();
console.log(arr)'; // (3) ['param1', 'param2', 'param3']
2、实现new
使用new
命令时,它后面的函数依次执行下面的步骤。
- 创建一个空对象,作为将要返回的对象实例。
- 将这个空对象的原型,指向构造函数的
prototype
属性。 - 将这个空对象赋值给函数内部的
this
关键字。 - 开始执行构造函数内部的代码。
function Person (name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHello = function () {
console.log('hello, my name is ' + this.name + ', i am ' + this.age + ' years old')
}
// 模拟es5-new
function _new () {
let args = [].slice.call(arguments);
let constructor = args.shift();
// console.log(constructor)
let context = Object.create(constructor.prototype);
let result = constructor.apply(context, args);
return (typeof result === 'Object' && result != null) ? result : context;
}
let p1 = _new(Person, '小明', 10);
p1.sayHello(); // hello, my name is 小明, i am 10 years old
// es6类
class Student {
constructor (weight, height) {
this.weight = weight;
this.height = height;
}
introduce() {
console.log(`weight: ${this.weight}, height: ${this.height}`)
}
}
let st2 = _new(Student, '51KG', '171cm')
st2.introduce(); // weight: 51KG, height: 171cm
3、vue的computed与watch的区别
当computed内有异步操作时无效,无法监听数据的变化
一个多对一或者一对一,一般用computed
4、两个异步请求返回的数据使用同一个列表渲染?
页面按钮A和B,分别是异步请求fa和fb,fa耗时1秒,fb耗时3秒,返回的列表使用同个列表组件渲染,问如何保证先点击A,后点击B,最后展示的是fb返回的数据?
方案1:使用标记A和B表示最后的请求,在fa,fb返回时判断标记,标记为A则使用fa返回的数据,反之亦然。
方案2: 物理避免,点击一个按钮时,所有按钮置灰,请求返回后,取消置灰。
5、rem的原理
rem是相对根元素(html)font-size大小的长度单位,常被用来做移动端适配
html {
font-size: 100px;
}
html的font-size:100px;则1rem = 100px;
.div {
width: 1rem;
height: 1rem;
background: red;
}
<div class="div"></div>
则div的长宽为100px。
移动端适配原理,根据屏幕宽度设置rem的值。
举例:屏幕宽度a:400px;
设计稿宽度b:360px;
设置html的font-size = (a / b) * 36 = 40px;那么1rem = 40px;
一个盒子的宽度1rem,则为40px;占1/10
相同的代码运行到宽度为300的屏幕c上。
设置html的font-size = (c / b)*36 = 30px;那么1rem = 30px;
盒子的宽度1rem,则为30px;占1/10
let width = document.documentElement.clientWidth;
document.getElementsByTagName('html')[0].style.fontSize = (width / 360) * 36 + 'px';
window.addEventListener('resize', function() {
let width = document.documentElement.clientWidth;
document.getElementsByTagName('html')[0].style.fontSize = (width / 360) * 36 + 'px';
})
6、预编译
全局预编译
发生时间:页面加载完成
步骤:
创建GO对象(global Object)全局上下文
找到变量声明,作为GO的属性名,赋值undefined
找到函数声明,作为GO的属性名,赋值函数体
局部预编译
发生时间:函数执行的前一刻
步骤:
创建AO对象(Activation Object),函数上下文
找到形参和变量声明,作为AO的属性,赋值undefined
形参和实参相统一,给AO的形参属性赋值
找到函数声明,作为AO的属性,赋值函数体
匿名函数均是作为函数表达式出现,不是函数声明,不参与预编译
预编译完成之后,代码进入执行期间,开始执行,执行步骤:
扫描整体语法语句
发现发逻辑错误或语法错误,程序停止执行
从上到下,解释一行,执行-行
7、原型
获取原型:prototype,__proto__,Object.getPrototypeof()
推荐使用Object.getPrototypeof()
__proto__只有实例才可以用。
function F() {
this.hello = 'hello'
}
var f = new F()
var a = f.__proto__
var b = F.prototype
var c = Object.getPrototypeOf(f)
console.log(a===b, a===c) // true true
8、forEach方法中 无法通过return break终止循环
break会使程序报错
return和continue只能是下面的代码不执行
9、数据类型
基本数据类型:undefined, null,string, number,boolean,
引用数据类型: Object, Array, Function,regExp
10、基本的两列自适应布局
a.网格
.box{
background-color: antiquewhite;
width: 100%;
height: 100px;
display: grid;
grid-template-columns: 10rem 1fr;
}
.left {
background-color: green;
}
.right {
background-color: red;
}
<div class="box">
<div class="left">left</div>
<div class="right">right</div>
</div>
b. 弹性盒子
.box{
background-color: antiquewhite;
width: 100%;
height: 100px;
display: flex;
}
.left {
width: 100px;
background-color: green;
}
.right {
width: 100%;
background-color: red;
}
<div class="box">
<div class="left">left</div>
<div class="right">right</div>
</div>
c. 定位
.box{
background-color: antiquewhite;
width: 100%;
height: 100px;
position: relative;
overflow: hidden;
}
.left {
width: 100px;
background-color: green;
}
.right {
width: 100%;
position: absolute;
left: 100px;
top: 0;
background-color: red;
}
<div class="box">
<div class="left">left</div>
<div class="right">right</div>
</div>
d.浮动
.box{
background-color: yellow;
width: 100%;
height: 100px;
position: relative;
}
.left {
width: 100px;
float: left;
background-color: green;
}
.right {
width: 100%;
background-color: red;
}
<div class="box">
<div class="left">left</div>
<div class="right">right</div>
</div>
11. 判断数组相等
[] == [] // false 因为数组是栈地址不同,所以不相等
[].toString() // ''
JSON.stringify([]) //'[]'
对象也是如此,
{} == {} // false