2021前端面试题-JS篇

JavaScript05

2021前端面试题-JS篇,第1张

```

当查找一个对象的某个属性时,会先从它自身的属性上查找,

如果找不到的话会从它的_proto_属性上查找,就是这个构造函数的prototype属性,

如果还没找到就会继续在_proto_上查找,直到最顶层,找不到则为undefined,

像这样一层一层去查找形成一个链式的称为原型链

```

new一个函数,中间发生了什么

1.开辟一个内存空间,也就是创建一个空对象,obj={}或obj=new Object()

2.将这个新对象的_proto_属性指向它构造函数的prototype

3.将构造函数this绑定为这个新对象,在空对象上挂在属性和方法(call或apply方式)

4.返回这个新对象

相同:都是改变函数上下文this指向

不同:bind返回的是一个函数,不会立即执行

         传参的不同 apply第二个参数为数组形式

         call apply都是对函数的直接调用

1.作为普通函数直接调用,this指向window

2.作为对象方法去调用的话,this指向调用它的这个对象

3.箭头函数,没有this,this取决于外层离它最近的非箭头函数的this

4.构造函数的this,指向创建这个构造函数的实例对象

1.词法作用域(静态作用域)

  js采用的就是词法作用域

  只有函数可以限定作用域

  函数允许函数访问外层作用域的变量

  函数在定义的时候决定了函数作用域,词法作用域关心函数在何处被定义

2.动态作用域

  函数在调用的时候决定了函数作用域,动态作用域关心函数在何处被调用

变量取值会到创建这个变量的函数作用域中去查找,如果找不到会向上查找,直到查找到全局作用域,这就形成了一个作用域链

1.节流

2.防抖

1.原型链继承

2.构造函数继承

3.组合继承(原型链继承+构造函数继承)

4.原型式继承

5.寄生继承

6.组合寄生继承

定义在一个函数内部的函数,这个内部函数有权访问外部函数作用域的变量

优点:

缺点:

js在运行中的任务,有一套收集,排队,执行的特殊机制,这种机制就是事件循环

遇到同步事件直接执行,遇到异步事件分为宏任务和微任务

如果微任务列表里有任务,先执行微任务再执行宏任务

块级作用域  暂时性死区  能否被修改

没有this  call apply方法修改this无效

没有prototype属性

没有argument

不能使用new  不能用作构造函数,会报错

持续更新中.......

首先我们看一段程序:

#include <stdio.h>

int x= 5

int f(){

return x

}

int g(){

int x = 1

return f()

}

int main(int argc,char*argv[]){

printf("%d ",g())

}

程序的输出会是1,还是5呢?答案是5,那原因是?

C语言采用的是静态作用域,即词法作用域,变量与值的绑定是通过检查程序的正文,在编译时期完成的,而与程序的运行流程无关。它扫描程序正文,选取最近遇到的那个绑定。

在采用动态作用域的语言里,变量与值的绑定是依赖于程序执行流程的,它是选取在运行的过程中所遇到的最近绑定。象上面的例子,如果C语言采用动态作用域的话,那输出结果将是1。

动态作用域易于实现,它只需顺势查找栈帧,查到谁,谁就和自己绑定。另外,有了动态作用域,可以随时拦截,改变程序的行为。在灵活的同时,随之而来的就是麻烦。为了确定程序的行为,必须仔细查看程序的具体执行流程,稍不小心就有可能引入bug。

静态作用域:包括C语言在内和它的同类的语言在内的大多数的语言使用静态作用域。C语言的作用域规则是基于程序结构的,一个声明的作用域由该声明在程序中出现的位置隐含地决定。稍后出现的语言,比如C++、Java和C#,也通过诸如public、private和protected等关键字的使用,提供了对作用域的明确控制。

动态作用域:如果一个作用域策略依赖于一个或多个只有在程序执行的时刻才能知道的因素,它就是动态的。

2. 静态作用域

典型:C, C++, Python, Java, JavaScript, Lua,大多数现在程序设计语言都是采用静态作用域规则。

静态作用域又叫做词法作用域,使用词法作用域的变量叫词法(lexical)变量。 词法变量都有一个确定的作用域和不确定的生存期。 词法变量的作用域可以是一个函数或block,使得其在这段代码区域内都有效。 但是词法变量的生存期取决于该变量需要引用(reference)多久(?)。

词法作用域里,对于函数体中的一个符号,不会逐层检查函数的调用链,而是检查函数定义时的外部环境,即捕捉的是函数定义时该符号的绑定。

3. 动态作用域

典型:Emacs Lisp, Common Lisp(两种都有), Perl(两种都有)。

使用动态作用域的变量叫做动态(dynamic)变量,有时也叫做特殊(special)变量。 动态变量具有不确定的作用域,只取决于在什么地方绑定它。 同时从绑定开始,到绑定时的代码段执行完毕,这就是动态变量的生存期。

动态作用域里,函数执行遇到一个符号,会由内向外逐层检查函数的调用链,并打印第一次遇到的那个绑定的值。显然,最外层的绑定即是全局状态下的那个值。