美文网首页
第6章 对象模式

第6章 对象模式

作者: 不系流年系乾坤 | 来源:发表于2016-11-07 15:35 被阅读10次

6.1 私有成员和特权成员

JavaScipt 对象的所有属性都是公有的,没有显式的方法指定某个属性不能被外界访问。

6.1.1 模块模式

模块模式是一种用于创建拥有私有数据的单件对象的模式。
基本做法是使用立即调用函数表达式(IIFE)来返回一个对象。原理是利用闭包。

var yourObj = (function(){
    // private data variables
    
    return {
        // public methods and properties
    }
}());

模块模式还有一个变种叫暴露模块模式,它将所有的变量和方法都放在 IIFE 的头部,然后将它们设置到需要被返回的对象上。

//  一般写法
var yourObj = (function(){
    var age = 25;
    
    return {
        name: "Ljc",
        
        getAge: function(){
            return agel
        }
    }
}());

// 暴露模块模式
var yourObj = (function(){
    var age = 25;
    function getAge(){
        return agel
    };
    return {
        name: "Ljc",
        getAge: getAge
    }
}());

6.1.2 构造函数的私有成员(不能通过对象直接访问)

模块模式在定义单个对象的私有属性十分有效,但对于那些同样需要私有属性的自定义类型呢?你可以在构造函数中使用类似的模式来创建每个实例的私有数据。

function Person(name){
    // define a variable only accessible inside of the Person constructor
    var age = 22;
    
    this.name = name;
    this.getAge = function(){
        return age;
    };
    this.growOlder = function(){
        age++;
    }
}

var person = new Person("Ljc");

console.log(person.age); // undefined
person.age = 100;
console.log(person.getAge()); // 22

person.growOlder();
console.log(person.getAge()); // 23

这里有个问题:如果你需要对象实例拥有私有数据,就不能将相应方法放在 prototype 上。

如果你需要所有实例共享私有数据。则可结合模块模式和构造函数,如下:

var Person = (function(){
    var age = 22;

    function InnerPerson(name){
        this.name = name;
    }

    InnerPerson.prototype.getAge = function(){
        return age;
    }
    InnerPerson.prototype.growOlder = function(){
        age++;
    };

    return InnerPerson;
}());

var person1 = new Person("Nicholash");
var person2 = new Person("Greg");

console.log(person1.name); // "Nicholash"
console.log(person1.getAge()); // 22

console.log(person2.name); // "Greg"
console.log(person2.getAge()); // 22

person1.growOlder();
console.log(person1.getAge()); // 23
console.log(person2.getAge()); // 23

6.2 混入

这是一种伪继承。一个对象在不改变原型对象链的情况下得到了另外一个对象的属性被称为“混入”。因此,和继承不同,混入让你在创建对象后无法检查属性来源。
纯函数实现:

function mixin(receiver, supplier){
    for(var property in supplier){
        if(supplier.hasOwnProperty(property)){
            receiver[property] = supplier[property];
        }
    }
}

这是浅拷贝,如果属性的值是一个引用,那么两者将指向同一个对象。

6.3 作用域安全的构造函数

构造函数也是函数,所以不用 new 也能调用它们来改变 this 的值。在非严格模式下, this 被强制指向全局对象。而在严格模式下,构造函数会抛出一个错误(因为严格模式下没有为全局对象设置 thisthis 保持为 undefined)。
而很多内建构造函数,例如 ArrayRegExp 不需要 new 也能正常工作,这是因为它们被设计为作用域安全的构造函数。
当用 new 调用一个函数时,this 指向的新创建的对象是属于该构造函数所代表的自定义类型。因此,可在函数内用 instanceof 检查自己是否被 new 调用。

function Person(name){
    if(this instanceof Person){
        // called with "new"
    }else{
        // called without "new"
    }
}

具体案例:

function Person(name){
    if(this instanceof Person){
        this.name = name;
    }else{
        return new Person(name);
    }
}

相关文章

  • js进阶(二)

    第十二天 04-基础进阶-第02天{对象进阶、内置对象} 第十二天对象工厂模式创建对象构造函数模式创建对象原型模式...

  • 《PHP设计模式大全》系列分享专栏

    php设计模式介绍之编程惯用法第1/3页 php设计模式介绍之值对象模式第1/5页 介绍php设计模式中的工厂模式...

  • 大话设计模式读书笔记-7代理模式

    第7章 为别人做嫁衣——代理模式 定义 代理模式,为其他对象提供一种代理以控制对这个对象的访问。 解释 代理对象和...

  • 大话设计模式读书笔记-9原型模式

    第9章 简历复印——原型模式 定义 原型模式,通过拷贝已有原型的方式创建对象的思想。 用原型实例指定创建对象的种类...

  • 代理模式

    本文参考《Android源码设计模式解析与实战第2版》 代理模式的定义 代理模式也称为委托模式,是为其他对象提供代...

  • 对象的创建与继承

    创建对象 工厂模式 => 构造函数模式 => 原型对象模式 => 构造函数模式+原型对象模式 工厂模式 构造函数模...

  • 第6章 对象模式

    6.1 私有成员和特权成员 JavaScipt 对象的所有属性都是公有的,没有显式的方法指定某个属性不能被外界访问...

  • Java设计模式之代理模式

    代理模式 模式介绍 代理模式是对象的结构模式。代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用...

  • 正则表达式

    使用演示 模式对象 使用演示 模式对象

  • 对象间交互模式

    对象间交互模式 对象间交互模式

网友评论

      本文标题:第6章 对象模式

      本文链接:https://www.haomeiwen.com/subject/lteouttx.html