内容简介: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
被强制指向全局对象。
而在严格模式下,构造函数会抛出一个错误(因为严格模式下没有为全局对象设置 this
, this
保持为 undefined
)。
而很多内建构造函数,例如 Array
、 RegExp
不需要 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); } } 复制代码
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 《JavaScript面向对象精要》之三:理解对象
- 《JavaScript面向对象精要》之四:构造函数和原型对象
- 《JavaScript面向对象精要》之五:继承
- 《JavaScript面向对象精要》之二:函数
- 《JavaScript面向对象精要》之一:基本类型和引用类型
- 《JavaScript面向对象精要》--构造函数和原型链读后总结
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。