Learning Records JavaScript进阶

背景:对JavaScript的深入学习参考:《JavaScript高级程序设计》《冴羽 JavaScript 深入》
从原型到原型链prototypeprototype是每个函数都会有的属性
function Person(){} Person.prototype.name = 'Kevin';var person1 = new Person();var person2 = new Person();console.log(person1.name) // Kevinconsole.log(person2.name) // Kevin一个函数的prototype指向一个对象,这个对象是构造函数所创建的实例原型原型是什么:每一个JavaScript对象创建时都会关联另一个对象(除NULL),这个对象就是原型,其他对象从原型继承属性也是上述例子中person1和person2的原型
Learning Records JavaScript进阶

文章插图
proto该属性是每个JavaScript对象所具有的属性,会指向该对象的原型承接上文有
console.log(person.__proto__ === Person.prototype) // true;
Learning Records JavaScript进阶

文章插图
同样也有一个construct函数指向原构造函数
console.log(Person === Person.prototype.construct) // true;
Learning Records JavaScript进阶

文章插图
实例和原型的关系当我们想去读取实例的属性时,如果找不到实例的属性 , 就去找与实例关联的原型的属性,如果还找不到 , 就找原型的原型,就这样不断向上递归,找到最顶层为止
function Person() {}Person.prototype.name = 'Kevin';var person = new Person();person.name = 'Daisy';console.log(person.name) // Daisydelete person.name;console.log(person.name) // Kevin实例和原型的具体关系如下:
Learning Records JavaScript进阶

文章插图
其中蓝色的线就是原型链
词法作用域和动态作用域作用域决定了当前代码对变量的访问权限词法作用域即静态作用域,函数的作用域在函数创建时决定 。动态作用域,函数的作用域在函数调用的时候决定 。
var value = https://www.huyubaike.com/biancheng/1;function foo() { console.log(value);}function bar() { var value = 2; foo();}bar();由于JavaScript采用的是静态作用域,所以在foo中查找value时会到函数的上层去找,输出是1如果是动态作用域,就会从调用函数的作用域中找,结果就是2
在《JavaScript权威指南》中有这样一个例子
var scope = "global scope";function checkscope(){ var scope = "local scope"; function f(){ return scope; } return f();}checkscope();var scope = "global scope";function checkscope(){ var scope = "local scope"; function f(){ return scope; } return f;}checkscope()();【Learning Records JavaScript进阶】这两段代码的执行结果其实都是“local scope”(因为其本质都是在执行f())根据词法作用域,所采用的变量是局部变量
执行上下文栈可执行代码:有三种,函数代码,全局代码 , eval代码当JavaScript执行到一个函数时,就会进行一定的准备工作(也叫执行上下文)JavaScript引擎创建了上下文栈(ECS)来方便地管理上下文让我们来模拟上下文执行地过程ECS = [] // 初始为空由于最先遇到的是全局代码globalContext,所以有ECS = [globalContext];并且会一直存在到程序结束如果此时遇到下面这段代码
function fun3() { console.log('fun3')}function fun2() { fun3();}function fun1() { fun2();}fun1();工作原理:当执行一个函数时,就会创建一个执行上下文 , 并且压入执行上下文栈,当函数执行完毕时,就会将执行上下文从栈中弹出相当于:ECS:[globalContext,fun1,fun2,fun3] ------------> ECS:[glovalContext];只有当调用一个函数时才会创建上下文再来看两个例子
var foo = function () { console.log('foo1');}foo(); // foo1var foo = function () { console.log('foo2');}foo(); // foo2function foo() { console.log('foo1');}foo(); // foo2function foo() { console.log('foo2');}foo(); // foo2由于JavaScript执行代码是一段一段地执行,并且会优先提取定义的函数式语句并执行在第二个例子中,第二次声明覆盖了第一次声明,所以都会输出foo2如果对其中一个进行变量提升,那么结果也会发生改变,这里不再赘述
变量对象全局上下文全局上下文中的全局变量指的就是全局对象在客户端JavaScript中,全局对象就是Windows对象
函数上下文在函数上下文中,用活动变量表示变量对象(AO)即在进入函数上下文后,变量对象才会变成活动对象
执行过程当进入执行上下文时,这时候还没有执行代码AO是进入函数上下文时被创建的,它通过函数的arguments进行初始化会包含函数的所有形参 , 变量声明 , 函数声明如遇到下面代码时

推荐阅读