码迷,mamicode.com
首页 > 其他好文 > 详细

闭包,原型链

时间:2015-12-27 23:15:40      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:

闭包

在【函数定义】的时候,【函数对象】的【scope属性】便会引用包含该函数的上一级函数在运行时所生成的【执行上下文】的【活动对象】,因为发生对象属性之间的相互依赖,导致包含此函数的【scope属性】所指向的活动变量,在上一级函数【执行完毕】将要【释放执行上下文】的时候【不能释放】其包含的【活动变量】。

自己的理解: 闭包的产生首先要有一个地址被引用所指向

函数与对象的关系

  1. 函数就是对象的一种
  2. 对象是函数创建的

prototype原型

  1. prototype是函数的一个属性
  2. 每一个构造函数都有prototype属性
  3. prototype的值实际上是一个对象
    • 这个对象默认只有一个constructor的属性,并且指向函数本身

构造函数中的属性和原型中的属性的区别

  1. 把属性定义在原型中比定义在构造函数中消耗的内存更小,因为在内存中一个类的原型只有一个,写在原型中的行为可以 被所有实例共享。实例化的时候并不会在内存中再复制一份。没有特殊原因,一般把属性写到类中,行为写到原型中。
  2. 使用原型的方式定义属性,实际上不同对象中的属性是共享的,也就是说对其中的任何一个对象修改了属性,其他对象的属性也会跟着发生变化,因为它们指向的是同一个地址,共享同一个属性
  3. 构造函数中定义的属性和方法比原型中定义的属性和方法优先级高。如果定义了同名称的属性和方法,构造函数中会覆盖原型中的。

隐式原型(对象)

隐式原型:_proto_是对象中的一个属性,每个对象都有一个_proto_属性,也称为隐式原型。并且指向创建该对象的prototype
  1. 自定义函数本质上都是通过Object函数来创建的,所以它的_proto_指向Object.prototype
  2. Object.prototype的_proto_指向null

原型链

原型链:若访问对象属性时,先在基本属性中找,如果自身没有该属性,便会沿着_proto_这条链往上找。

执行上下文

在一段js代码执行前,浏览器已经做了一些准备工作,其中包括对变量的声明,变量赋值是在赋值语句执行的时候进行的。

准备工作有三步:

  1. 变量:变量的声明,默认赋值为undefined
  2. this:赋值
  3. 函数声明:赋值

这三种数据的准备情况称之为“执行上下文”或者“执行上下文环境”;

函数每被调用一次,都会产生一个新的执行上下文环境,因为不同的调用可能会有不同的参数。
函数定义的时候就应经确定了函数体内部变量的作用域

执行上下文栈

执行全局代码时,会产生一个全局上下文环境,每次调用函数,又会产生函数上下文环境,当函数调用完成时,这个上下文环境及其中的数据都会被销毁。再重新回到全局上下文环境。

处于活动状态的执行上下文环境只有一个。(压栈和出栈的过程)

作用域和执行上下文

除全局作用域之外,每个函数都会创建自己作用域。作用域在函数定义时就已经确定了,而不是在调用时确定。 作用域只是一个“地盘”,一个抽象的概念,其中没有变量,要通过作用域对应的执行上下文来获取变量的值,同一作用域下,不同的调用会产生不同的执行上下文环境,继而产生不同的值。

自由变量

在一个作用域中使用的变量,没有在其中声明(即在其他作用域中声明的),此时,这个变量对这个作用域来讲就是自由变量(也可称为活动变量)

作用域链

  1. 先在当前作用域查找X,如果有则获取并结束,如果没有则继续;
  2. 如果当前作用域是全局作用域,则证明X未定义,结束;否则继续;
  3. 将创建该函数的作用域作为当前作用域;
  4. 跳转到第一步。

继承

  1. 对象冒充

        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();
    
  2. 原型链的方式

    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);
    
  3. 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);
    
  4. 混合方式

    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();

闭包,原型链

标签:

原文地址:http://www.cnblogs.com/Shirley-He/p/5081102.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!