《JavaScript面向对象精要》之六:对象模式

栏目: 后端 · 前端 · 发布时间: 5年前

内容简介:JavaScript 对象的所有属性都是公有的,没有显式的方法指定某个属性不能被外界访问。模块模式是一种用于创建模块模式还有一个变种叫暴露模块模式,它将所有的变量和方法都放在

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

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


// 暴露模块模式
var yourObj = (function(){
  var age = 25;
  function getAge(){
    return age;
  };
  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);
  }
}
复制代码

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

CASIO fx-5800P编程计算器公路与铁路施工测量程序

CASIO fx-5800P编程计算器公路与铁路施工测量程序

2011-8 / 40.00元

《CASIO fx-5800P 编程计算器公路与铁路施工测量程序(第2版)》内容简介:第2版是一本全新的图书。书中的QH2-7T与QH2-8T程序都具有三维中边桩坐标正、反算,路基超高及边桩设计高程计算,边坡坡口与坡脚计算,桥墩桩基坐标计算,隧道超欠挖计算等功能。QH2-7T为交点法程序,QH2-8T为线元法程序,两个程序均使用数据库子程序输入平竖曲线的全部设计数据。测试程序各项功能所用的案例均取......一起来看看 《CASIO fx-5800P编程计算器公路与铁路施工测量程序》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

在线进制转换器
在线进制转换器

各进制数互转换器

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试