function Person(name, age, job) {
this.name = name; this.age = age; this.job = job; this.friends = ["Shelby", "Court"]; }Object.defineProperties(Person.prototype, {
"constructor": { enumerable: false, value: Person, }, "sayName": { enumerable: true, value: function() { console.log(this.name) } } })var person1 = new Person("Nicholas", 29, "Software Engineer");
// 6.2.5动态原型模式————将原型封装到构造函数中:function Person(name, age, job) {
this.name = name; this.age = age; this.job = job;// 只在第一次使用构造函数时if块内的语句才会执行
if (typeof this.sayName.toLowerCase() != "function") { Person.prototype.sayName = function() { console.log(this.name); } } }var person1 = new Person("Nicholas", 29, "Software Engineer");
// 6.2.6 寄生构造函数模式————用于为原生构造函数定义新的方法,避免污染原生构造函数function Person(name, age, job) {
var obj = new Object(); obj.name = name; obj.age = age; obj.job = job; obj.sayName = function() { console.log(this.name); } return obj; }// 与工厂模式的区别是多了一个new操作符
var person1 = new Person("Nicholas", 29, "Software Engineer");// ________________________________________________________________________
//寄生构造函数模式可以构造基于特殊对象(如数组)创建的具有指定方法的特殊对象
function SpecialArray() { var values = new Array(); values.push.apply(values, arguments); values.toPipedString = function() { return values.join("|"); } return values; } // 6.2.7 稳妥构造函数模式————将变量封装到构造函数内部,不能通过对象属性访问,只能通过对象方法访问function Person(name, age, job) {
var obj = new Object(); obj.sayName = function() { console.log(name); } return obj }var person1 = Person("jusing");
// 只能通过person1.sayName()方法访问"jusing";person1对象实例中没有name属性 // 6.3.3 组合继承模式(原型链+构造函数) // !!!!!!!最常用的继承方法!!!!!!!//先定义超类型构造函数,绑定属性
function SuperType(name) { this.name = name; this.colors = ["red", "blue", "green"]; }// 再定义超类型构造函数的原型,绑定方法;
SuperType.prototype.sayName = function() { console.log(this.name); } // 定义子类型构造函数 function SubType(name, age) {// 通过向子类型传参,设置子类型实例的属性值;
SuperType.call(this, name); this.age = age; }// 将子类型的原型设置为超类型的对象实例
SubType.prototype = new SuperType(); Subtype.sayAge = function() { console.log(this.age); } // 6.3.4 原型式继承————直接以对象实例为原型创建构造函数并返回子类型对象实例// ECMAScript为原型式继承提供了原生方法: Object.create(obj, [A-V Object]),这个方法接受两个参数,第一个是原型对象,第二个为键值对象(可选)
function object(obj) { function F() {}; F.prototype = obj; return new F(); }var person = {
name: "jusing", friends: ["Shelby", "Court", "Van"] }person1 = object(person);
// 6.3.5 寄生式继承————在主要考虑对对象实例的继承而不是自定义子类型对象的属性时,简单易用function createAnother(obj) {
var clone = Object.create(obj); // 增强对象的方法 clone.sayHi = function() { console.log("Hi!"); } return clone; } // 注意在使用寄生式继承方法为对象添加方法时不能做到方法的复用,会浪费大量的资源 // 6.3.6 寄生组合式继承————避免在超类型.prototype上创建多余的属性,还能保证原型链的不变。 // 这是开发人员普遍认为最完美的继承方法function inheritPrototype(subtype, supertype) {
// 创建超类型的原型对象作为子类型的原型
var prototype = Object.create(supertype.prototype);// 将超类型的原型.constructor指向子类型构造函数
prototype.constructor = subType;// 将子类型构造函数的原型指向超类型的原型
subType.prototype = prototype; }//先定义超类型构造函数,绑定属性
function SuperType(name) { this.name = name; this.colors = ["red", "blue", "green"]; }// 再定义超类型构造函数的原型,绑定方法;
SuperType.prototype.sayName = function() { console.log(this.name); } // 定义子类型构造函数 function SubType(name, age) {// 通过向子类型传参,设置子类型实例的属性值;
SuperType.call(this, name); this.age = age; }// 实现寄生组合继承方法
inheritPrototype(SubType, SuperType);// 为超类型的原型(此时已成为子类型构造函数的原型)添加方法
SubType.prototype.sayAge = function() { console.log(this.age); } // 6.3.7 深度克隆————完全克隆一个引用值,但是不包括其原型链function deepClone(origin, target) {
var target = target || {}, toStr = Object.prototype.toString, arrStr = "[object Array]";for(var prop in origin) {
// 过滤掉origin.prototype原型链上的属性
if (origin.hasOwnProperty(prop)) {// 针对origin上非null的对象属性
if(origin[prop] !== "null" && typeof(origin[prop]) == "object") {// 判断是否为origin[prop]是否为数组对象
if(toStr.call(origin[prop]) == arrStr) { target[prop] = []; }// 否则为对象
else { target[prop] = {}; }// 对数组与对象属性进行递归方法
deepClone(origin[prop], target[prop]); }// 字符串等基本类型直接copy
else { target[prop] = origin[prop]; } } } return target; }
// 7.4 私有变量————只能通过特权方法访问函数内部变量
function MyObject() {
// 创建私有变量和私有函数
var privateVriable = 10; function privateFunction() { return false; }// 特权方法
this.publicMethod = function() { console.log(privateVriable ++, privateFunction()); } } // 这种方法会导致特权方法重复绑定,复用性不好7.4.1 静态私有变量————解决私有方法的复用性问题
(function() {
// 创建私有变量和私有函数 var privateVriable = 10; function privateFunction() { return false; }// 使用构造函数及原型绑定私有变量与函数
MyObject = function() {}; //这里没有用new操作符,将MyObject定义为全局变量,函数执行后可访问//原型
MyObject.prototype.publicMethod = function() { console.log(privateVriable ++, privateFunction()); } }) 7.4.3 增强的模块模式————私有变量、方法复用、对象增强var singleton = function() {
var privateVriable = 10; function privateFunction() { return false; }var object = new CustomType();
object.publicProperty = true;
object.publicMethod = function() {
console.log(privateVriable ++, privateFunction()); } return object; }();