在【函数定义】的时候,【函数对象】的【scope属性】便会引用包含该函数的上一级函数在运行时所生成的【执行上下文】的【活动对象】,由于发生对象属性之间的相互依赖,致使包含此函数的【scope属性】所指向的活动变量,在上一级函数【执行完毕】将要【释放执行上下文】的时候【不能释放】其包含的【活动变量】。浏览器
本身的理解: 闭包的产生首先要有一个地址被引用所指向闭包
在一段js代码执行前,浏览器已经作了一些准备工做,其中包括对变量的声明,变量赋值是在赋值语句执行的时候进行的。app
函数每被调用一次,都会产生一个新的执行上下文环境,由于不一样的调用可能会有不一样的参数。 函数定义的时候就应经肯定了函数体内部变量的做用域
执行全局代码时,会产生一个全局上下文环境,每次调用函数,又会产生函数上下文环境,当函数调用完成时,这个上下文环境及其中的数据都会被销毁。再从新回到全局上下文环境。函数
处于活动状态的执行上下文环境只有一个。(压栈和出栈的过程)this
除全局做用域以外,每一个函数都会建立本身做用域。做用域在函数定义时就已经肯定了,而不是在调用时肯定。 做用域只是一个“地盘”,一个抽象的概念,其中没有变量,要经过做用域对应的执行上下文来获取变量的值,同一做用域下,不一样的调用会产生不一样的执行上下文环境,继而产生不一样的值。prototype
在一个做用域中使用的变量,没有在其中声明(即在其余做用域中声明的),此时,这个变量对这个做用域来说就是自由变量(也可称为活动变量)code
对象冒充对象
function Person(name, age) { this.name = name; this.age = age; this.sayName = function() { console.log(this.name); }; } function Student(name, age) { this.obj = Person; this.obj(name, age); delete this.obj; this.study = function() { console.log("study"); } } var stu1 = new Student("zhangsan", 21); console.log(stu1.name, stu1.age); stu1.sayName(); stu1.study();
原型链的方式继承
function Person(name, age) { this.name = name; this.age = age; this.sayName = function () { console.log(this.name); }; } function Student(name, age) { this.constructor(name, age); } Student.prototype = new Person(); var stu1 = new Student("zhangsan", 21); console.log(stu1.name, stu1.age);
call和apply方法内存
function Student(name, age) { // Person.call(this, name, age); Person.apply(this, [name, age]); } var stu = new Student("zhangsan", 21); console.log(stu.name, stu.age);
混合方式
function Person(name, age) { this.name = name; this.age = age; } Person.prototype.sayName = function() { console.log(this.name); }; function Student(name, age) { Person.call(this, name, age); } Student.prototype = new Person();