js 设计模式及其应用

107 阅读2分钟

设计模式

许多设计模式主要是为了封装变化,通过封装变化把稳定不变的部分和容易变化的部分隔离开来,在系统演变过程中只需要替换那些容易变化的部分

《《设计模式》》书中归纳了23种设计模式,分别划分为三类

  1. 创建型模式:目的封装创建对象的变化,例如构造函数的构造器模式,用来初始化对象的属性和方法,封装不可变的key,传入可变的value
  2. 结构型模式封装对象之间的组合关系
  3. 行为型模式封装的是对象的行为变化

js 原型

js 实际是基于原型的一种面向对象语言,对象系统是使用原型模式搭建

因此所有的对象都是从某个对象上克隆来的,根对象是null

原型编程范例:

  1. 所有数据都是对象
  2. 要得到一个对象,找到一个对象为原型并克隆它
  3. 对象会记住它的原型,如果对象无法响应请求,会委托给它自己的原型

从js 实现来看,对象的构造器有原型,对象把请求委托给它自己的原型

this

this 指向:分4种情况

  1. 作为对象的方法调用

    1. 函数作为对象的方法被调用时,this指向该对象
  2. 作为普通函数调用

    1. 函数不作为对象的属性被调用时,this总是指向全局对象
  3. 构造器调用

    1. new调用构造函数总会返回一个对象,this指向这个对象
  4. call,aooly调用

    1. call,apply 改变借用的对象的this方向,指向借用者

丢失的this

当对象的方法被赋值给后调用,就是普通函数调用,this指向全局对象,会出现丢失this现象

var obj={
  myName:"sven",
  getName:function (){
    return this.myName
  }
}
console.log(obj.getName()) //作为对象的方法被调用,输出sven
var getName2=obj.getName;
console.log(getName2()) // 作为普通函数被调用,输出undefined

call 和apply的用途

  1. 改变this指向

    var obj1={
    name:"sven"
    }
    var obj2={
    name:"anne"
    }
    window.name="window"
    var getName=function (){alert("this.name")}
    getName() // 输出window
    getName.call(obj1) //输出sven
    getName.call(obj2) //输出anne
    
  2. bind

    function.prototype.bind=function(context){
    var self=this
    return function (){
     return self.apply(context,arguments)
    }
    }
    var obj={name:"sven"}
    var func = function(){
    alert(this.name) //输出:sven
    }.bind(obj)
    func()
    
  3. 借用其他对象的方法

    var A=function(name){
     this.name=name
    }
    var B=function (){
     A.apply(this,arguments)
    }
    B.prototype.getName = function(){
    return this.name;
    };
    var b = new B( 'sven' );
    console.log( b.getName() ); // 输出: 'sven'