看《JavaScript高级程序设计》做的一些笔记
工厂模式: 1 2 3 4 5 6 7 8 9 10 function createPerson (arguments ) { var o = new Object (); o.name = name; o.age = age; o.sayName = function ( ) {}; return o; } var person1 = createPerson(arguments );
解决创建多个相似对象的问题
缺点: 没有解决对象识别问题
构造函数模式: 1 2 3 4 5 6 7 8 9 function Person (arguments ) { this .name = name; this .age = age; this .sayName = function ( ) {}; } var person1 = new Person(arguments );var person2 = new Person(arguments );
构造函数名大写字母开头 person1有constructor(构造函数)属性,指向Person
1 2 3 person1.constructor == Person person1 instanceof Object person1 instanceof Person
构造函数当做普通函数使用,属性和方法都添加给window
缺点: 每个方法在每个实例上都要重新创建一遍 person1.sayName == person2.sayName //false
原型模式: 每个函数都有一个prototype属性,指向一个对象,这个对象可以包含特定类型所有实例共享的属性和方法
1 2 3 4 5 6 7 8 9 10 11 12 function Person ( ) {} Person.prototype.name = 'myName' ; Person.prototype.age = 66 ; Person.prototype.sayName = function ( ) {}; var person1 = new Person();var person2 = new Person();person1.name == person2.name
可以通过对象实例访问原型中的值,但不能通过对象实例重写原型中的值
1 2 3 person1.name = 'newName' ; person1.name person2.name
访问属性时,若没有在实例中搜索到该属性,就会在原型中搜索并返回该属性 使用delete可以删除实例中的属性,此时再访问该属性则会返回原型中的属性
1 2 delete person1.name;person1.name
原型与in操作符:
通过对象能够访问属性时返回true(for-in返回能够通过对象访问的、可枚举的属性),无论是在实例中还是原型中
原型模式的一些方法:
1 2 3 4 5 6 isPrototypeOf() Person.prototype.isPrototypeOf(person1) Object .getPrototypeOf() 返回[[Prototype]]的值Object .getPrototypeOf(person1) == Person.prototype Object .getPrototypeOf(person1.name)
hasOwnProperty() 检测一个属性是否存在于实例中
1 2 3 person1.name = 'newName' ; person1.hasOwnProperty('name' ); person2.hasOwnProperty('name' );
hasPrototypeProperty() 检测一个属性是否来自原型
1 2 hasPrototypeProperty(person1,'name' ); hasPrototypeProperty(person2,'name' );
Object.keys() 取得对象上所有可枚举的实例属性
Object.getOwnPropertyNames() 获取所有实例属性,无论是否可枚举
原型的对象字面量写法
1 2 3 4 5 6 7 function Person ( ) {} Person.prototype = { name:'myName' , age:66 , sayName:function ( ) {} };
这种写法的constructor属性不再指向Person,而是指向Object构造函数
1 2 3 4 5 var person3 = new Person();person3 instanceof Person person3 instanceof Object person3.constructor == Person person3.constructor == Object
缺点: 由于其共享的特性,对于包含引用类型值的属性,实例无法有属于自己的属性 例如属性中包含数组,若通过实例对象对数组进行修改,由于数组存在于prototype中,则会影响到所有的实例。
组合使用构造函数模式和原型模式(广泛使用): 构造函数模式定义实例属性,原型模式用于定义方法和共享的属性
1 2 3 4 5 6 7 8 9 10 11 function Person (arguments ) { this .name = name; this .age = age; this .friends = ['a' ,'b' ]; } Person.prototype = { constructor :Person , sayName :function ( ){} };
动态原型模式: 1 2 3 4 5 6 7 8 9 10 11 function Person (arguments ) { this .name = name; this .age = age; if (typeof this .sayName != 'function' ){ Person.prototype.sayName = function ( ) {}; Person.prototype.otherFunction = function ( ) {}; } }
寄生构造函数模式: 1 2 3 4 5 6 7 8 9 10 11 12 function Person (arguments ) { var o = new Object (); o.name = name; o.age = age; o.sayName = function ( ) {}; return o; } var person1 = new Person(arguments );
除了使用new和构造函数,这个模式跟工厂模式是一样的
例如要创建一个具有额外功能的Array,由于不能直接修改Array,可以这样:
1 2 3 4 5 6 7 8 9 function SpecialArray ( ) { var sa = new Array (); sa.push.apply(sa,arguments ); sa.newFunction = function ( ) {}; } var arr = new SpecialArray(arguments );arr.newFunction();
稳妥构造函数模式(安全性考虑): 1 2 3 4 5 6 7 8 9 10 11 function Person (name,age ) { var o = new Object (); o.sayName = function ( ) { return name; } return o; } var person1 = Person(name,age);person1.sayName();
参考:《JavaScript高级程序设计》(第3版)