面向对象的程序设计

理解JavaScript对象

  1. JavaScript创建对象的方法
// new Object()
let obj1 = new Object()
// 对象字面量
let obj2 = {
	name1: "name1",
	sayName: function() {
		return this.name
	}
}
  1. 在JavaScript对象中每个属性都有4个特性, 可以用defineProperty来修改
  • [[Configurable]] (默认为true,能否删除,修改,一旦将其设置为false,将不能再设置为true)
  • [[Enumerable]] (能否通过for in 循环获取,默认为true)
  • [[Writable]] (能否修改属性的值,默认为true)
  • [[Value]] (读取和写入属性的时候对应这个位置)。
Object.defineProperty(obj2, 'name1', {
	writable: false,
	value: 'wang'
})
obj2.name1 = "!23"
console.log(obj2.name1); 				// wang

在调用defineProperty创建一个新属性的时候,Configurable, Enumerable, Writable 默认都为false

  1. 访问器属性
  • [[Configurable]] (默认为true,能否删除,修改,一旦将其设置为false,将不能再设置为true)
  • [[Enumerable]] (能否通过for in 循环获取,默认为true)
  • [[Get]] 默认undefined
  • [[Set]] 默认undefined
var book = {
    _year : 2004,
    edition : 1
};
Object.defineProperty(book,"year",{ 
    get : function () {
        return this._year;
    },
    set : function (newValue) {
        if (newValue > 2004) {
            this._year = newValue;
            this.edition += newValue - 2004;
        }
    }
});
book.year = 2005;
console.log(book.edition);   	// 2
  1. 读取属性特性 Object.getOwnPropertyDescriptor()

创建对象

创建工厂模式(设计模式)
  • 优点:解决创建多个重复对象的问题
  • 缺点:没办法识别person对象属于哪个类型
// 工厂模式

function createPerson(name, age, job) {
    let obj = new Object();
    obj.name = name;
    obj.age = age;
    obj.job = job;
    obj.sayName = function() {
        return this.name;
    }
    return obj;
};

let person1 = createPerson("name1", 11, "Engineer");
let person2 = createPerson("name2", 12, "Student");
构造函数模式
  • 优点: 工厂模式优点 + 可以识别对象的类型
  • 缺点: 不能重用function属性,每个对象都新建一遍function
// 构造函数模式

function Person(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function() {
        return this.name;
    }
};

let person3 = new Person("name1", 11, "Engineer");
let person4 = new Person("name2", 12, "Student");

alert(person4.sayName == person3.sayName);          // false

new 的过程

  1. 创建一个新的对象
  2. 将构造函数的作用域赋值给新对象(this指向了新对象)
  3. 执行构造函数中的代码(为这个新对象[this]添加属性)
  4. 返回新对象(返回this)
原型模式
  • 原型上的属性和方法在实例上可以共享
  • 优点:共享
  • 缺点:方法适合共享,但属性不适合共享
// 原型模式

function Person() {
};

Person.prototype.name = "Name1";
Person.prototype.age = 11;
Person.prototype.job = "students";
Person.prototype.sayName = function() {
    return this.name;
}
let person3 = new Person();
person3.sayName();   // Name1
let person4 = new Person();
person4.sayName();   // Name1
alert(person4.sayName == person3.sayName);          // true
组合使用构造函数和原型模式(推荐使用)
  • 原则: 共享属性在prototype中定义,实例属性在构造函数中定义
// 组合使用构造函数和原型模式
function Person(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
};

Person.prototype = {
    constructor: Person,
    sayName: function() {
        return this.name;
    }
};

let person1 = new Person("name1", 11, "Engineer");
let person2 = new Person("name2", 12, "Student");
alert(person1.name == person2.name)             // false
alert(person1.sayName == person2.sayName)       // true

动态原型模式
  • 简介:用构造函数的样子实现 “组合使用构造函数和原型模式(推荐使用)”。类似语法糖。
  • 注意:动态原型模式不能重写构造函数的原型,会切断构造函数中原型操作

// 动态原型模式
// 在第一次new时候将共享属性添加到构造函数的原型(prototype)中
function Person(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    if (typeof this.sayName != "function") {
        Person.prototype.sayName = function() {
            return this.name
        }
    }
};
寄生构造函数模式
我觉得不用了解了。。。。。。。。。。。。。。。。。。。。。。。。。。。。。简直疑难杂症
稳妥构造函数模式
  • 简介:通过闭包实现私有变量的构造函数,
  • 与工厂模式的区别:工厂模式将属性挂在return的对象上return出去,稳妥构造函数没有将属性挂在object上直接return出去

function Person(name) {
    var o = new Object;
    let _name = name;
    o.sayName = function() {
        return _name;
    }
    return o;
}

let person = Person("Wang");
alert(person.sayName())   // Wang
alert(person.name)       // undefined

继承

原型链(一般不用)
  • 实现方式: 子类的原型指向父类的实例
  • 子类的prototype === 子类实例化的__proto__属性
  • 缺点:
  1. 属性也被继承
  2. 子类没办法传值给父类的同时不影响其他对象实例

/// prototype 
function SuperType() {
    this.superString = "superString";
}

SuperType.prototype.getSupertring = function() {
    return this.superString;
}

function SubType() {
    this.subString = "subString"
}



SubType.prototype = new SuperType();
SubType.prototype.getSubString = function() {
    return this.subString;
}

let sub = new SubType();
sub.getSubString()				//    "subString"
sub.getSupertring()				//    "superString"
SubType.prototype === sub.__proto__ 			// true
借用构造函数(经典继承)
  • 优点: 解决原型链继承缺点
  • 缺点: function都在父类中定义的化,每次都会新建而不是复用
// 解决原型链继承缺点1
function SuperType() {
    this.color = ['red', 'blue', 'yellow']
}

function SubType() {
    // 继承SuperType
    SuperType.call(this);
}
let ins1 = new SubType();
ins1.color.push("green");
alert(ins1.color)       // red, blue, yellow, green

let ins2= new SubType();
alert(ins2.color)       // red, blue, yellow
  1. 传递参数
function SuperType(args) {
    this.color = args
}

function SubType(args) {
    // 继承SuperType,同时还传递了参数,可以将公共类的属性放到父类
    SuperType.call(this, args);
    // 特有属性放在子类
    this.age = 12
}
let ins1 = new SubType("green");
alert(ins1.color)       //  green
alert(ins1.age)

let ins2 = new SubType("green2");
alert(ins1.color)       //  green2
alert(ins1.age)
组合继承(最常用)
  • 简介:结合借用构造函数继承和原型链继承两种方式实现
// 1. 父类构造函数 存储属性
function SuperType(name) {
    this.name = name || "no name";
    this.colors = ["red", "blue"];
}
// 2. 父类原型 存储公用方法
SuperType.prototype.sayName = function() {
    return this.name;
}

// 3. 子类构造函数
function SubType(name, age) {
    // 4. 继承SuperType构造函数中的属性,同时还传递了参数,可以将公共类的属性放到父类
    SuperType.call(this, name);
    // 特有属性放在子类
    this.age = age;
}

// 5. 建立supertype的原型方法
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
// 6. 子类公共方法
SubType.prototype.sayAge = function() {
    return this.age;
}

let ins1 = new SubType("name11", 23);
ins1.colors.push("testColor");
alert(ins1.colors)          //  red, blue, testColor
alert(ins1.sayName())       //  name11
alert(ins1.sayAge())        //  23

let ins2 = new SubType("name22", 22);
alert(ins2.colors)          //  red, blue
alert(ins2.sayName())       //  name22
alert(ins2.sayAge())        //  22
原型式继承

object.create() 原理

寄生式继承
寄生组合式继承
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值