js 词法作用域,动态作用域,作用域链,原型链,闭包,执行上下文

作用域

事实上JavaScript并不具有动态作用域,它只有词法作用域,简单明了,但是this机制某种程度上很像动态作用域

词法作用域

是一套引擎如何寻找变量以及会在何处找到变量的规则,它是定义在词法阶段的作用域,是由写代码时将变量和块作用域写在哪里来决定的。

动态作用域

动态作用域并不关心函数和作用域是如何声明以及在何处声明的,只关心它们从何处调用。类似this的指向问题。

作用域链

A(B(C{ console.log(xxx)}))                     A中有B,B中有C。则C中打印xxx变量的时候会向上找直到找到第一个匹配的为止,否则返回undefind  

原型

在JavaScript中,每当定义一个函数数据类型(普通函数、类)时候,都会天生自带一个prototype属性,这个属性指向函数的原型对象,并且这个属性是一个对象数据类型的值。

让我们用一张图表示构造函数和实例原型之间的关系:

image

 

原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问到这个原型对象,我们可以将对象中共有的内容,统一设置到原型对象中。

相当于java类中的static 变量

原型链

调用属性,会顺着属性原型链一直查找。

    function Person() {}
    Person.prototype.a = 123;
    Person.prototype.sayHello = function () {
      alert("hello");
    };
    var person = new Person()
    console.log(person.a)//123
    console.log(person.hasOwnProperty('a'));//false
    console.log('a'in person)//true

person实例中没有a这个属性,从 person 对象中找不到 a 属性就会从 person 的原型也就是 person.__proto__ ,也就是 Person.prototype中查找,很幸运地得到a的值为123。那假如 person.__proto__中也没有该属性,又该如何查找?

当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型,一直找到最顶层Object为止。Object是JS中所有对象数据类型的基类(最顶层的类)在Object.prototype上没有__proto__这个属性。

 

console.log(Object.prototype.__proto__ === null) // true

 

闭包

闭包是通过改变JS回收机制保留某段作用域的一种手段。当一个函数执行完毕后,里面的局部变量是会被JS自带的垃圾回收机制给销毁的,从而释放内存。但是如果返回一个函数,而且函数里面有用到父级数声明的变量,那么此时,变量不会被回收,因为还有可能被用到,并且外界可以通过函数访问这段作用域下的变量。

闭包的作用:

xxx

执行上下文

参考 https://www.cnblogs.com/wilber2013/p/4909430.html

JavaScript解释器会创建执行上下文 Execution Context,其实这里会有两个阶段:

  • 创建阶段(当函数被调用,但是开始执行函数内部代码之前)

    • 创建 作用域链 Scope chain
    • 创建 变量对象 VO/AO(variables, functions and arguments)
    • 设置this的值
  • 激活/代码执行阶段

    • 设置变量的值、函数的引用,然后解释/执行代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

life1024

你的鼓励将是我创作的最大动力。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值