• JavaScript 高级特性


    1. 原型Prototype

    1.1 构造函数

      所谓"构造函数",其实就是一个普通函数,但是内部使用了this变量。对构造函数使用new运算符,就能生成实例,并且this变量会绑定在实例对象上。  

    function Cat(name, color) {
        this.name = name;
        this.color = color;
    }
    
    var cat1 = new Cat("大毛", "黄色");
    var cat2 = new Cat("二毛", "黑色");
    alert(cat1.name); // 大毛
    alert(cat1.color); // 黄色
    
    //这时cat1和cat2会自动含有一个constructor属性,指向它们的构造函数。
    cat1.constructor == Cat; //true
    cat2.constructor == Cat; //true
    
    function Cat(name, color) {
        this.name = name;
        this.color = color;
        this.type = "猫科动物";
        this.eat = function () { alert("吃老鼠"); };
    }
    
    cat1.type; // 猫科动物
    cat1.eat(); // 吃老鼠
    //每一个实例对象,每一次生成重复内容内存,但是内存地址不一样
    cat1.eat == cat2.eat; //false

    1.2 实例.constructor

      每个构造函数生成实例的时候 会自带一个constructor属性 指向该构造函数。对于普通对象生成实例时,constructor指向其类型的构造函数。

      结论1: 实例.constructor == 构造函数

    function Cat(name) {
        this.name = name;
    }
    var cat1 = new Cat("大毛");
    cat1.constructor == Cat; //true
    
    var str1 = "123";
    str1.constructor == String;//true

    1.3 实例.prototype

      构造函数都有一个prototype属性,指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承

      对该构造函数的实例,继承的prototype对象都指向同一个。    

      结论2: 实例1.prototype.func == 实例2.prototype.func

    function Cat(name, color) {
        this.name = name;
        this.color = color;
    }
    Cat.prototype.type = "猫科动物";
    Cat.prototype.eat = function () { alert("吃老鼠") };
    
    cat1.eat == cat2.eat;//true
    // hasOwnProperty判断是自己本身的属性还是继承的
    cat1.hasOwnProperty("name"); //true
    cat1.hasOwnProperty("type"); //false

    1.4 实例.__proto__ 

      Javascript创建对象时(普通对象和函数对象),都会内置一个__proto__属性,指向 实例的创建函数(实例.constructor).prototype

      结论3: 实例.__proto__ === 构造函数.prototype 

      同理: 构造函数.prototype.__proto__ === Object.prototype 

    2. 作用域Scope

    2.1 全局变量

      全局声明的变量,浏览器环境实际上声明在顶层变量"window"下。

      函数内部声明变量时,未使用var关键字,会声明为全局变量。  

    function f1() {
        n = 999;
    }
    f1();//调用函数时,n被注册到全局
    alert(n); // 999
    alert(window.n); // 999

      

    2.2 局部变量

      只能在局部使用并可见的变量,如函数内部声明的变量  

    function f2() {
        var n = 999;
        alert(n);//999
    }
    alert(n);//报错

    2.3 链式作用域

      父对象的所有变量,对子对象都是可见的,反之则不成立

    //子对象会一级一级地向上寻找所有父对象的变量
    function f1() {
        var n = 999;
        function f2() {
            //n对f2可见
            alert(n); // 999
        }
    }

    3. 闭包Closure

       什么是闭包; 定义在一个函数内部的函数 (闭包就是能够读取其他函数内部变量的函数)

    //下面的f2就是一个闭包
    function f1() {
        var n = 999;
        function f2() {
            alert(n);
        }
        return f2;
    }
    var result = f1();
    result(); // 999
    //注意result后跟的(),这对括号才是实际调用

    用途:

    • 读取函数内部的变量
    • 让函数内部变量的值始终保持在内存中

    闭包执行时的this指针指向问题

    var name = "The Window";
    var object = {
        name: "My Object",
        getNameFunc: function () {
            return function () {
                return this.name;
            };
        }
    };
    
    alert(object.getNameFunc()());//The Window
    //上面这句解开后等于 
    alert(function () { return this.name; }()); //此时this指针指向当前域下的name="The Window"
    var name = "The Window";
    var object = {
        name: "My Object",
      getNameFunc: function () {
       var that = this;
          return function () {
              return that.name;
         };
      }
    };
    
    alert(object.getNameFunc()());//My Object
    //分解如下
    alert(function () { return that.name; }());//that是对object内部this变量的引用, object内部this指向实例本身
    alert(function () { return object.name; }());//最终如此

    refers:

    http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_encapsulation.html

    http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html

  • 相关阅读:
    word-wrap和word-break的区别
    transform 二维转变
    过渡
    新闻下滑导航案例
    background-origin,clip
    边框图片
    背景样式
    线性渐变与径向渐变与重复渐变
    边框阴影
    盒模型和圆角
  • 原文地址:https://www.cnblogs.com/full-stack-engineer/p/8824478.html
Copyright © 2020-2023  润新知