老几把登

Better Thinking, Better Coding

javascript 高级程序设计读书笔记

javascript 高级程序设计读书笔记

面向对象

  1. javascript没有类的概念,通过函数实现构造函数,通过new运算符来创建对象

    function Person(name, age, job) {
      this.name = name;
      this.age = age;
      this.friends = ["A","B"];
      this.sayname = function(){
        alert(this.name);
    	};
    }
    
    var P = new Person("P",22,"coder");
    
  2. Person与普通函数并无区别,如果直接调用则是向this(window)对象添加属性

  3. 用new操作符实现了4个步骤:

    • 创建新对象;
    • 将构造函数中的作用域赋给新对象(this指向新对象)
    • 执行构造函数中的代码
    • 返回新对象
  4. 上述方法称为构造函数模式,每一个对象互相独立,其属性和方法都独立创建,耗费空间,尤其是方法,不必要独立创建。

  5. 原型模式:每一个函数都有一个原型属性,默认的原型属性有一个constructor域指向函数,原型为所有函数new出的对象所共有。类似于c++中的static属性或方法。下例为推荐写法

    function Person() {
      this.name = name;
      this.age = age;
      this.friends = ["A","B"];
    }
    //原型模式写法1,在默认prototype上补充
    Person.prototype.sayName = function() {
      alert(this.name);
    }
    Person.prototype.startid = 0; //共享
    //写法2,覆盖默认的prototype
    Person.prototype = {
     	constructor : Person, // 注意覆盖写法应加入constructor属性
      sayName: function(){
        alert(this.name);
    	}
      startid:0
    }
    

所有对象共享Prototype域,而构造函数里添加的域是独立的。对象构造完以后如果再给prototype中的域赋值可以将其覆盖,注意不是删除,因为如果将自己新加的delete之后,prototyoe中的就又出现了。

  1. 动态原型模式:在构造函数中解决原型的初始化,只有构造的第一个对象会触发if条件,填充Person的原型

    function Person(name, age, job) {
      this.name = name;
      this.age = age;
      this.job = job;
      if (typeof this.sayName != "function") { // 检查一个属性就行
        Person.prototype.sayName = fuction() {
          alert(this.name);
    		}
        Person.prototype.startid = 0;
      }
    }
    
  2. 继承——利用原型链 (不能解决所有子类原型共用一个超类实例的问题,不推荐用)

    function SuperType() {
      this.property = true;
    }
    SuperType.prototype.getSuperValue = function() {
      return this.property;
    };
    function SubType() {
      this.subproperty = false;
    }
    //继承
    SubType.prototype = new SuperType();
    SubType.prototype.getSubValue = function() {
      return this.subproperty;
    }
    var instance = new SubType();
    

但是,由于SubType没有重定义constructor,所以继承了SuperType的constructor。但是constructor不影响instanceof

  1. 借用构造函数: 不是new一个父类对象,而是调用构造函数向子类添加父类的域,所以子类无法访问父类的原型中的内容,不推荐使用

    function SuperType() {
      this.colors = ["red","blue"];
    }
    fuction SubType() {
      SuperType.call(this); // 借用构造函数,在子类中再构造一次父类
    }
    
  2. 组合继承:调用两次父类构造函数,效率低,此方法子类的constructor也是错的

    function SuperType(name) {
      this.name = name;
      this.colors = ["red","blue","green"];
    }
    SuperType.prototype.sayName = function() {
      alert(this.name);
    };
    function SubType(name, age) {
      SuperType.call(this,name); // 借用父类构造函数
      this.age = age;
    }
    SubType.prototype = new SuperType(); //原型继承
    SubType.prototype.sayAge = function() {
      alert(this.age);
    }
    
  3. 寄生组合式:推荐使用,用此函数替代组合继承的的 SubType.prototype = new SuperType();

    // 书中写法,constructor在原型里
    function object(o) {
      function F(){}
      F.prototype = o;
      return new F();
    }
    function inheritPrototype(subType, superType) {
      var prototype = object(superType.prototype); //拷贝原型
      prototype.constructor = subType;						 //添加constructor
      subType.prototype = prototype;						   //指定原型
    }
    //网上的另一个写法, 感觉也是对的, 区别是constructor不在原型里。
    SubType.prototype = SuperType.prototype;
    SubType.constructor = SubType;
    
  4. 有关prototype、constructor和__proto__的关系参考下面这篇文章,写的很清晰

    https://blog.csdn.net/cc18868876837/article/details/81211729

  5. 闭包:定义在函数内的函数,内层函数拥有指向外层函数活动记录的指针,可以访问外层函数的变量。

  6. 私有权限:用闭包实现,有this的是公有权限,var的是非公有权限

    function MyObject() {
      //私有变量和私有函数
      var privateVariable = 10;
      function privateFunction() {
        return false;
      }
      //特权方法,外界可调用
      this.publicMethod = function() {
        privateVariable++;
        return privateFunction();
      }
    }
    var m = new MyObject();
    

    静态私有:解决上述中函数不共享的问题,私有变量和prototype是共享的

    (function(){
      //私有
      var privateVariable = 10;
      function privateFunction() {
        return false;
      }
      MyObject = function(value) { //函数中不带var的变量是全局变量
      };
      MyObject.prototype.publicMethod = function() {
    		privateVariable++;
        return privateFunction();
      };
    })();
    var m = new MyObject(value);
    
posted @ 2020-03-30 21:12  老几把登  阅读(126)  评论(0编辑  收藏  举报