前端面经整理二

7 篇文章 0 订阅

BFC是什么

BFC:block formatting context(块级格式化上下文)
它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>清除浮动</title>
</head>
<style>
    .par {
        border: 5px solid rgb(91, 243, 30);
        width: 300px;
        overflow: hidden;
    }
    
    .child {
        border: 5px solid rgb(233, 250, 84);
        width:100px;
        height: 100px;
        float: left;
    }
</style>
<body>
    <div class="par">
        <div class="child"></div>
        <div class="child"></div>
    </div>
</body>
</html>

const、var、let

const相当于定义一个常量,不可改变以及重复声明,但是注意的是const定义出来的常量只是指变量的地址不变,所以在定义引用类型的时候可以改变其中的属性,比如:
在这里插入图片描述
var具有声明提升的效果,也就是说在执行js上下文的时候会先将变量的声明提前到最上面,并且可以重复声明和定义
let不具有声明提升,可以重复定义,有块作用域

块级作用域

ES5只有全局作用域和函数作用域,ES6的let相当于增加了块级作用域的使用
如:

function f1() {
  let n = 5;
  if (true) {
    let n = 10;
  }
  console.log(n); // 5
}

在for循环的使用:

for(let i=0;i<5;i++){
setTimeout(()=>{
console.log(i);
})
}

相当于在块作用域里会重复声明i

for(let i=0;i<5;i++){
let i=块作用域的i
setTimeout(()=>{
console.log(i);
})
}

有关函数的使用:
我们知道没有块作用域的时候内层变量会覆盖外层变量
那这样呢:

function f() { console.log('I am outside!'); }

(function () {
  if (false) {
    // 重复声明一次函数f
    function f() { console.log('I am inside!'); }
  }

  f();
}());

会打印undefined,因为等同于:

在这里插入代码片/ 浏览器的 ES6 环境
function f() { console.log('I am outside!'); }
(function () {
  var f = undefined;
  if (false) {
    function f() { console.log('I am inside!'); }
  }

  f();
}());
// Uncaught TypeError: f is not a function

自己实现call、apply、bind方法

关于call、apply、bind的使用方法和区别我之前已经整理过一次了,但是面试问让我自己实现的时候还是GG
拿call方法来梳理一下流程:
1.将函数绑定为对象的属性来使用
2.执行一次函数
3.删除这个属性

Function.prototype.mycall=function(context){
        if(typeof this!=='function'){
             return 'error';
        }
        context=context||window;
        context.fn=this;
        let result=null;
        let arg=[...arguments].slice(1);
      
        result=context.fn(...arg);
        delete context.fn;
        return result;
    }
    function bar(){
        console.log(1);
        console.log(this.name);
        console.log(arguments);
    }
    let obj={
        name:'张三'
    };
    bar.mycall(obj,2,3,4,5,6);

在这里插入图片描述
apply只是传参数的方式不同:

 Function.prototype.myapply=function(context){
        if(typeof this!=='function'){
             return 'error';
        }
        context=context||window;
        context.fn=this;
        let result=null;
        let arg=[...arguments].slice(1);
        if(arguments[1]){
            result=context.fn(...arg);
        }
        else{
            result=context.fn();
        }
       
        delete context.fn;
        return result;
    }
    function bar(){
        console.log(1);
        console.log(this.name);
       
    }
    let obj={
        name:'张三'
    };
    bar.myapply(obj,2,3,4,5,6);

bind函数

Function.prototype.mybind=function(){
    let self=this;
    let context=[].shift.call(arguments);
    let arg=[].slice.call(arguments);
    return function(){
       return self.apply(context,[].concat.call(arg,[].slice.call(arguments)));
    }
}
function f(y, z){
    return this.x + y + z;
}
var m = f.mybind({x : 1}, 2);
console.log(m(3));
//6

由于arguments是类数组对象而不是数组所以不能直接调用数组的方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值