前端面试

引言

网上面试多的数都数不过来,但那都是别人的总结。你看一眼就感觉自己记住了吗,结果一问吱吱语语,有点印象。

原型

参考于冴羽 https://github.com/mqyqingfeng/Blog

原型:
每一个JavaScript对象(null除外)在创建的时候就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型"继承"属性。

每一个JavaScript对象(除了 null )都具有的一个属性,叫__proto__,这个属性会指向该对象的原型

function Person(){}
var person = new Person()

以上来说就是
构造函数的prototype指向原型
实例的__proto__指向原型

Person.prototype == person.__proto__ //true

构造函数,实例对象都可以指向原型,那原型是否有属性指向构造函数和实例呢

指向实例的到是没有 因为一个构造函数可以生成多个实例
指向构造函数倒是有的 constructor
每个原型都有一个constructor属性 指向关联的构造函数

console.log(Person === Person.prototype.constructor) //true
console.log(Person === person.__proto__.constructor) //true

还有一点上面 person.constructor时 其实person中并没有constructor属性,读取到constructor时,
会从person的原型也就是Person.prototypr中读取

  • 所有对象都含有__proto__
  • 只有函数才有prototype
  • 所有函数的默认原型都是Object的实例
console.log(Object.__proto__ == Function.prototype)
console.log(Person.__proto__ == Function.prototype)
console.log(Function.__proto__ == Function.prototype)
console.log(Object.prototype.__proto__ == null)

//Function.prototype 是个function 类型的对象

引发为什么Object.prototype.proto == null呢。参考于掘金-Autumn秋田 https://juejin.im/post/6844903930216841230
typeof Object.prototye === 'object',说明他是一个object类型的对象,如果他是由Object函数生成的,那么Object.prototype.__proto__ === Object.prototype。那么Object.prototype.__proto__指向自身,那么以__proto__属性构成的原型链将没有终点了,所以为了让原型链有终点。Javascript规定,Object.prototype.__proto__ === null

很长 很枯燥 也要认真看完
这里说typeOf 那么问题可以有判断类型的几种方式,区别是什么 嗯嗯Object.prototype.toString.call() instanceof constructor啊区别呢 还有......
说到原型 接着就是一堆继承 this什么的 比如继承的几种方式,ES6与ES5继承区别呢,怎么用ES5的显示ES6的继承呢 烦躁啊 静静

执行上下文Execution context stack

参考掘金 ,js高三

  • 全局代码
  • 函数代码
  • eval代码
    JavaScript 开始要解释执行代码的时候,最先遇到的就是全局代码
    所以初始化的时候首先就会向执行上下文栈压入一个全局执行上下文,
    程序结束之前,最底部永远有个 globalContext

每个执行上下文都有3个重要的属性

  • 变量对象
  • 作用域链
  • this指向

变量对象

  1. 函数的所有形参(如果是函数上下文)
    • 由名称和对应值组成的一个变量对象的属性被创建
    • 没有实参,属性值设为undefined
  2. 函数声明
    • 由名称和对应值(函数对象(function-object))组成一个变量对象的属性被创建
    • 如果变量对象已经存在相同名称的属性,则完全替代这个属性
  3. 变量声明
    • 由名称和对应值(undefined)组成一个变量对象的属性被创建
    • 如果变量名称跟已经声明的形式参数或函数相同,则变量声明不会干扰已经存在的这类属性

作用域

作用域是指程序源代码中定义变量的区域。
作用域规定了如何查找变量,也就是确定当前执行代码对变量的访问权限。
JavaScript 采用词法作用域(lexical scoping),也就是静态作用域。
函数的作用域在函数定义的时候就决定了

作用域链 当查找变量的时候,会先从当前上下文的变量对象中查找,如果没有找到,就会从父级(词法层面上的父级)执行上下文的变量对象中查找,一直找到全局上下文的变量对象,也就是全局对象。这样由多个执行上下文的变量对象构成的链表就叫做作用域链。

闭包

参考讶羽 https://github.com/mqyqingfeng/Blog/issues/9

MDN

闭包是指那些能够访问自由变量的函数。

自由变量

自由变量是指在函数中使用的,但既不是函数参数也不是函数的局部变量的变量。

每本书中对闭包的定义都不一样

《JavaScript权威指南》从技术的角度讲,所有的JavaScript函数都是闭包:它们都是对象,它们都关联到作用域链。

从实践角度:以下函数才算是闭包:

  • 即使创建它的上下文已经销毁,它仍然存在(比如,内部函数从父函数中返回)
  • 在代码中引用了自由变量
posted @ 2020-08-12 12:01  spadek  阅读(147)  评论(0编辑  收藏  举报