【前端疑问】【学习笔记】 前端学习之路

目录

1、arguments类数组转化为数组,[].slice.call()与Array.prototype.slice.call(),为什么不可以用Array.prototype?

2、实现new

3、vue的computed与watch的区别

4、两个异步请求返回的数据使用同一个列表渲染?

5、rem的原理

6、预编译

7、原型

8、forEach方法中 无法通过return break终止循环

9、数据类型

10、基本的两列自适应布局

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命令时,它后面的函数依次执行下面的步骤。

  1. 创建一个空对象,作为将要返回的对象实例。
  2. 将这个空对象的原型,指向构造函数的prototype属性。
  3. 将这个空对象赋值给函数内部的this关键字。
  4. 开始执行构造函数内部的代码。
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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值