2020.11.17——作用域、作用域链、原型、原型链、执行上下文、三栏布局

JS基础 && CSS面试题 -2020.11.17

  • a. JS基础

     i. 了解作用域 && 作用域链, 执行上下文, 原型。 要注意作用域和原型, 作用域链和原型链的区别。
    

执行上下文

变量或函数的上下文决定了它们可以访问哪些数据,以及它们的行为。
每个上下文都有一个关联的变量对象(variable 	object),
而这个上下文中定义的所有变量和函数都存在于这个对象上。

在浏览器中,全局上下文就是我们常说的 window 对象,因此所有通过 var 定义的全局变量和函数都会成为 window 对象的属性和方法。

注意:使用 let 和 const 的顶级声明不会定义在全局上下文中,但在作用域链解析上效果是一样的。

上下文在其所有代码都执行完毕后会被销毁,包括定义在它上面的所有变量和函数
(全局上下文在应用程序退出前才会被销毁,比如关闭网页或退出浏览器)

上下文栈

每个函数调用都有自己的上下文。当代码执行流进入函数时,函数的上下文被推到一个上下文栈上。
在函数执行完之后,上下文栈会弹出该函数上下文,将控制权返还给之前的执行上下文。
ECMAScript程序的执行流就是通过这个上下文栈进行控制的。

作用域

作用域说明:指一个变量的作用范围。在 JavaScript 中, 作用域为可访问变量,对象,函数的集合。
1、全局作用域
	全局作用域在进入浏览器时被创建、退出浏览器时被销毁。
var a = 10;
b = 20;
function an(){
    console.log('an')
}
var bn = function(){
    console.log('bn')
}
console.log(window)
//变量a,b和函数an,bn都保存在window对象上

2、函数作用域
	函数作用域在函数被调用时创建,在函数执行完毕时被销毁

作用域链

上下文中的代码在执行的时候,会创建变量对象的一个作用域链(scope chain)。
这个作用域链决定了各级上下文中的代码在访问变量和函数时的顺序。
代码正在执行的上下文的变量对象始终位于作用域链的最前端。
如果上下文是函数,则其活动对象(activation object)用作变量对象。
活动对象最初只有一个定义变量: arguments 。(全局上下文中没有这个变量。)
作用域链中的下一个变量对象来自包含上下文,再下一个对象来自再下一个包含上下文。
以此类推直至全局上下文;全局上下文的变量对象始终是作用域链的最后一个变量对象。

代码执行时的标识符解析是通过沿作用域链逐级搜索标识符名称完成的。
搜索过程始终从作用域链的最前端开始,然后逐级往后,直到找到标识符。(如果没有找到标识符,那么通常会报错。)
例一:
var color = "blue";
function changeColor() {
if (color === "blue") {
color = "red";
} else {
color = "blue";
}
}
changeColor();
对这个例子而言,函数 changeColor() 的作用域链包含两个对象:
一个是它自己的变量对象(就是定义 arguments 对象的那个),
另一个是全局上下文的变量对象。
这个函数内部之所以能够访问变量color ,就是因为可以在作用域链中找到它。
例二:局部作用域中定义的变量可用于在局部上下文中替换全局变量
var color = "blue";
function changeColor() {
let anotherColor = "red";
function swapColors() {
let tempColor = anotherColor;
anotherColor = color;
color = tempColor;
// 这里可以访问 color、anotherColor 和 tempColor
}
// 这里可以访问 color 和 anotherColor,但访问不到 tempColor
swapColors();
}
// 这里只能访问 color
changeColor();

以上代码涉及 3 个上下文:全局上下文、 changeColor() 的局部上下文和 swapColors() 的局部
上下文。

下图展示了例二的作用域链

原型

1、每个函数都会创建一个 prototype 属性(指向原型对象),这个属性是一个对象,包含应该由特定引用类型的实例共享的属性和方法。
实际上,这个对象就是通过调用构造函数创建的对象的原型。
使用原型对象的好处是,在它上面定义的属性和方法可以被对象实例共享。
原来在构造函数中直接赋给对象实例的值,可以直接赋值给它们的原型。
2、默认情况下,所有原型对象自动获得一个名为 constructor 的属性,指回与之关联的构造函数。
3、在自定义构造函数时,原型对象默认只会获得 constructor 属性,其他的所有方法都继承自Object 。
4、每次调用构造函数创建一个新实例,这个实例的内部 [[Prototype]] 指针就会被赋值为构造函数的原型对象。
脚本中没有访问这个 [[Prototype]] 特性的标准方式,但 Firefox、Safari 和 Chrome会在每个对象上暴露 __proto__ 属性,通过这个属性可以访问对象的原型。
5、实例与构造函数原型之间有直接的联系,但实例与构造函数之间没有。

原型链
在这里插入图片描述

每个构造函数都有一个原型对象,原型有一个属性constructor指回构造函数,而实例有一个内部指针_proto_指向原型。
如果原型是另一个类型的实例呢?
那就意味着这个原型本身有一个内部指针_proto_指向另一个原型,相应地另一个原型也有一个指针指向另一个构造函数。
这样就在实例和原型之间构造了一条原型链。这就是原型链的基本构想。

作用域和原型的区别

作用域:是说明一个变量、对象、函数的作用范围

原型:是一个对象

作用域链和原型链的区别

原型链:原型链作用在构造函数上,操作的是构造函数的属性:实例属性和原型属性

作用域链:作用域链作用域普通函数上,操作的是全局变量和局部变量
  • b. CSS面试题

      实现一个三栏布局,左右容器固定,中间容器自适应。至少五种方式!
    
1、使用grid布局

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        *{
            margin:0;
        }

        .grid{
            display:grid;
            border:2px yellow solid;
            grid-template-columns:200px auto 200px;
        }
        div{
            border:2px red solid;
        }
    </style>
</head>
<body>
<div class="grid">
    <div><h4>这是左边容器</h4>
        <p>你好</p>
        <p>他好</p>
        <p>大家好</p>
    </div>
    <div><h4>这是中间容器</h4>
        <p> 他好</p>
    </div>
    <div><h4>这是右边容器</h4>
        <p> 大家好</p>
    </div>
</div>
</body>
</html>
2、使用flex布局+float

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        *{
            margin:0;
        }

        .flex{
            display:flex;
            border:2px yellow solid;
        }
        .left{
            float:left;
            width:200px;
        }
        .right{
            float:right;
            width:200px;
        }
        .middle{
            width:100%;
        }
        div{
            border:2px red solid;
        }
    </style>
</head>
<body>
<div class="flex">
    <div class="left"><h4>这是左边容器</h4>
        <p>你好</p>
        <p>他好</p>
        <p>大家好</p>
    </div>
    <div class="middle"><h4>这是中间容器</h4>
        <p> 他好</p>
    </div>
    <div class="right"><h4>这是右边容器</h4>
        <p> 大家好</p>
    </div>
</div>
</body>
</html>
3、使用flex布局+justify-content:space-between

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        *{
            margin:0;
        }

        .flex{
            display:flex;
            justify-content:space-between;
            border:2px yellow solid;
        }
        .left{
            width:200px;
        }
        .right{
            width:200px;
        }
        .middle{
            width:100%;
        }
        div{
            border:2px red solid;
        }
    </style>
</head>
<body>
<div class="flex">
    <div class="left"><h4>这是左边容器</h4>
        <p>你好</p>
        <p>他好</p>
        <p>大家好</p>
    </div>
    <div class="middle"><h4>这是中间容器</h4>
        <p> 他好</p>
    </div>
    <div class="right"><h4>这是右边容器</h4>
        <p> 大家好</p>
    </div>
</div>
</body>
</html>
4、使用flex布局+flow-grow

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        *{
            margin:0;
        }

        .flex{
            display:flex;
            border:2px yellow solid;
        }
        .left{
            flex-grow:0;
            width:200px;
        }
        .right{
            flex-grow:0;
            width:200px;
        }
        .middle{
            flex-grow:1;
        }
        div{
            border:2px red solid;
        }
    </style>
</head>
<body>
<div class="flex">
    <div class="left"><h4>这是左边容器</h4>
        <p>你好</p>
        <p>他好</p>
        <p>大家好</p>
    </div>
    <div class="middle"><h4>这是中间容器</h4>
        <p> 他好</p>
    </div>
    <div class="right"><h4>这是右边容器</h4>
        <p> 大家好</p>
    </div>
</div>
</body>
</html>
5、使用position:fixed
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        *{
            margin:0;
        }

        .flex{
            display:flex;
            border:2px yellow solid;
        }
        .left{
            position:fixed;
            left:0;
            width:200px;
        }
        .right{
            position:fixed;
            right:0;
            width:200px;
        }
        .middle{
            position:fixed;
            left:202px;
            right:202px;
        }
        div div{
            border:2px red solid;
            height:100px;
        }
    </style>
</head>
<body>
<div >
    <div class="left"><h4>这是左边容器</h4>
        <p>你好</p>
        <p>他好</p>
        <p>大家好</p>
    </div>
    <div class="middle"><h4>这是中间容器</h4>
        <p> 他好</p>
    </div>
    <div class="right"><h4>这是右边容器</h4>
        <p> 大家好</p>
    </div>
</div>
</body>
</html>
6、使用position:absolute
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        *{
            margin:0;
        }

        .super{
            position:relative;
            border:2px yellow solid;
        }
        .left{
            position:absolute;
            left:0;
            width:200px;
        }
        .right{
            position:absolute;
            right:0;
            width:200px;
        }
        .middle{
            position:absolute;
            left:202px;
            right:202px;
        }
        div div{
            border:2px red solid;
            height:100px;
        }
    </style>
</head>
<body>
<div >
    <div class="left"><h4>这是左边容器</h4>
        <p>你好</p>
        <p>他好</p>
        <p>大家好</p>
    </div>
    <div class="middle"><h4>这是中间容器</h4>
        <p> 他好</p>
    </div>
    <div class="right"><h4>这是右边容器</h4>
        <p> 大家好</p>
    </div>
</div>
</body>
</html>

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值