You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
function createPerson(name, age, job) {
var o = new Object()
o.name = name
o.age = age
o.job = job
o.sayName = function() {
alert(this.name)
}
return o
}
var person = createPerson("faker", 18, "LOL")
缺点:对象无法识别,方法不能共享
2. 构造函数模式
function Person(name, age, job) {
this.name = name
this.age = age
this.job = job
this.sayName = function() {
alert(this.name)
}
}
var person = new Person("faker", 18, "LOL")
缺点:还是方法共享问题
2.1 构造函数模式优化
function Person(name, age, job) {
this.name = name
this.age = age
this.job = job
this.sayName = sayName
}
function sayName() {
alert(this.name)
}
var person = new Person("faker", 18, "LOL")
缺点:方法共享了,但谈不上封装,每增加一个方法就得在外面再定义一个函数
3. 原型模式
function Person() {}
Person.prototype = {
constructor: Person, // 重写原型对象会切断原型与构造函数之间的联系,我们应该纠正它
name: "faker",
age: 18,
job: "LOL",
sayName() {
alert(this.name)
},
}
var person = new Person()
function Person(name, age, job) {
this.name = name
this.age = age
this.job = job
}
Person.prototype = {
constructor: Person,
sayName() {
alert(this.name)
},
}
var person = new Person("faker", 18, "LOL")
集构造函数和原型模式二者之长,这是JavaScript中用的最常用的一种模式
5. 动态原型模式
function Person(name, age, job) {
this.name = name
this.age = age
this.job = job
if (typeof this.sayName != "function") {
Person.prototype.sayName = function() {
alert(this.name)
}
}
}
var person = new Person("faker", 18, "LOL")
具有更好的封装性
6. 寄生构造函数模式
function Person(name, age, job) {
var o = new Object()
o.name = name
o.age = age
o.job =job
o.sayNmae = function() {
alert(this.name)
}
return o
}
var person = new Person("faker", 18, "LOL")
不太了解有什么用
7. 稳妥构造函数模式
function Person(name) {
var o = new Object()
o.sayName = function() {
alert(name)
}
return o
}
var person = Person("faker")
在某些安全环境中会用到这种模式,因为只有sayName方法可以访问到name,它有两个特点:
不使用this
不使用new创建对象
仔细看看,其实这是闭包的一种应用
继承的方式
1. 原型链
function SuperType() {
this.name = "faker"
}
SuperType.prototype.getName = function() {
return this.name
}
function SubType() {
}
// 继承了SuperType
SubType.prototype = new SuperType()
SubType.prototype.constructor = SubType
var instance = new SubType()
alert(instance.getName()) // faker
缺点:
包含引用类型的值会被所有实例共享(原型不就是用来共享的?)
子类原型成为了父类的一个实例,父类实例中的属性也变成了原型中的属性(我们想要的是一个纯净的原型)
2. 借用构造函数
function SuperType(name){
this.name = name
}
function SubType(name){
SuperType.call(this, name)
}
var instance = new SubType("faker")
alert(instance.name) // faker
缺点:仅使用借用构造函数无法避免构造函数存在的共享问题
3. 组合继承
function SuperType(name) {
this.name = name
}
SuperType.prototype.getName= function() {
return this.name
}
function SubType(name) {
// 继承了属性
SuperType.call(this, name)
}
// 继承了方法
SubType.prototype = new SuperType()
SubType.prototype.constructor = SubType
var instance = new SubType("faker")
alert(instance.getName()) // faker
缺点:虽然集原型链和构造函数二者之长,但有两个问题:
调用了两次父构造函数
实例的name会屏蔽掉SubType原型中的name,其实原型中的name的存在是没有意义的
4. 原型式继承
function object(o) {
function F() {}
F.ptototype = o
return new F()
}
var o = {
name: "faker"
}
var obj = object(o)
alert(obj.name) // faker
// 更好的方式
var obj1 = Object.create(o)
alert(obj1.name) // faker
面向对象
《JavaScript高级程序设计》笔记
创建对象的方式
1. 工厂模式
缺点:对象无法识别,方法不能共享
2. 构造函数模式
缺点:还是方法共享问题
2.1 构造函数模式优化
缺点:方法共享了,但谈不上封装,每增加一个方法就得在外面再定义一个函数
3. 原型模式
缺点:实例只有共享属性和方法,没有自身的属性,这还不是它最大的问题,最大的问题是它共享本质所导致的;例如,在原型中存在一个引用类型的数组,那么所有实例都会共享该数组,通过实例操作数组会在所有实例中反映出来。
4. 组合模式
集构造函数和原型模式二者之长,这是JavaScript中用的最常用的一种模式
5. 动态原型模式
具有更好的封装性
6. 寄生构造函数模式
不太了解有什么用
7. 稳妥构造函数模式
在某些安全环境中会用到这种模式,因为只有
sayName
方法可以访问到name,它有两个特点:仔细看看,其实这是闭包的一种应用
继承的方式
1. 原型链
缺点:
2. 借用构造函数
缺点:仅使用借用构造函数无法避免构造函数存在的共享问题
3. 组合继承
缺点:虽然集原型链和构造函数二者之长,但有两个问题:
4. 原型式继承
这是道格拉斯提出的一种,以现有对象为原型来创建新对象的方式,ES5中用
Object.create()
规范了这种方式5. 寄生式继承
顾名思义,这是一种寄生在原型式继承之上的一种模式
6. 寄生组合式继承
寄生组合式继承是寄生式继承和借用构造函数的组合,相比组合继承,它只调用了一次父构造函数,因此在子类的原型上也没有了多余的属性。这是目前最理想的继承范式。
The text was updated successfully, but these errors were encountered: