东莞网站建设硅胶,国外wordpress模板,重庆市建设工程信息网官网公示,wordpress主题页脚信息修改类是面向对象的设计模式#xff0c;它包括实例化、继承和多态
1、理论
面向对象变成强调的是数据和操作的行为本质上是相互关联的#xff0c;因此好的设计就是把数据以及和他相关的行为打包#xff08;封装#xff09;起来#xff0c;我们也叫他数据结构。
类的一个核心…类是面向对象的设计模式它包括实例化、继承和多态
1、理论
面向对象变成强调的是数据和操作的行为本质上是相互关联的因此好的设计就是把数据以及和他相关的行为打包封装起来我们也叫他数据结构。
类的一个核心概念就是多态这个概念是说父类的通用行为可以被子类用更特殊的行为重写实际上相对多态性允许我们从重写行为中引用基础行为。
在相当长的一段时间里JS只有一些近似类的语法元素比如说new和insranceof只不过后来在ES6中新增了一些元素比如class关键字但是这并不意味着JS这种实际上有类由于类是一种设计模式所以可以使用一些方法近似实现类的功能JS则提供了近似类的语法
在软件设计中类是一种可选的模式你需要自己决定是否在 JS 中使用它
2、类的机制
类与对象的关系可以看做房屋图纸与实际房屋类实例之间的关系
类实例通常是由一个特殊的类方法构造的这个方法名通常和类名相同被称作构造函数。这个方法的任务就是初始化实例需要的所有信息
class CoolGuy {specialTrick nothingCoolGuy( trick ) {specialTrick trick}showOff() {output( Heres my trick: , specialTrick )}
}类构造函数属于类而且通常和类同名。此外构造函数大多数需要用new来调这样语言引擎才可以构造一个新的类实例
3、类继承
在面向类的语言中我们可以先定义一个类然后定义一个继承前者的类
在传统的面向类的语言中 super 还有一个功能就是从子类的构造函数中通过super 可以直接调用父类的构造函数。通常来说这没什么问题因为对于真正的类来说构造函数是属于类的。然而在 JavaScript 中恰好相反——实际上“类”是属于构造函数的类似Foo.prototype… 这样的类型引用。由于JavaScript 中父类和子类的关系只存在于两者构造函数对应的 .prototype 对象中因此它们的构造函数之间并不存在直接联系从而无法简单地实现两者的相对引用。
多态并不表示子类和父类有关联子类得到的只是父类的一份副本。类的继承其实就是复制。
看下面的伪代码
class Vehicle {engines 1ignition() {output( Turning on my engine. );}drive() {ignition();output( Steering and moving forward! )}
}
class Car inherits Vehicle {wheels 4drive() {inherited:drive()output( Rolling on all , wheels, wheels! )}
}
class SpeedBoat inherits Vehicle {engines 2ignition() {output( Turning on my , engines, engines. )}pilot() {inherited:drive()output( Speeding through the water with ease! )}
}4、混入
在继承或者实例化时JS的对象机制并不会自动执行复制行为。简单来说JS中只有对象并不存在可以被实例化的类。但是由于在其他语言中类表现出来的都是复制行为因此JS使用了混入的方法来模拟类这个行为分为显示和隐式
4.1、显式混入
通常显式混入在许多框架中被称为extend…但是为了方便理解我们称之为mixin…
function mixin(sourceObj, targetObj) {for (var key in sourceObj) {// 只会在不存在的情况下复制if (!(key in targetObj)) {targetObj[key] sourceObj[key];}}return targetObj;
}
var Vehicle {engines: 1,ignition: function () {console.log(Turning on my engine.);},drive: function () {this.ignition();console.log(Steering and moving forward!);}
};
var Car mixin(Vehicle, {wheels: 4,drive: function () {Vehicle.drive.call(this); // 这就是显式多态console.log(Rolling on all this.wheels wheels!);}
});从技术角度来说函数实际上没有被复制复制的是函数引用。
Vehicle.drive.call(this);就是显式多态在之前的伪代码中对应的语句是inherited:drive()称之为相对多态。
JS在ES6之前并没有相对多态的机制所以由于Car和Vehicle中都有drive函数为了指明调用对象我们必须使用绝对引用通过名称显示指定Vehicle对象并调用它的drive函数。
还有混合复制以及寄生继承这里就不具体介绍了
2、隐式混入
隐式混入和显示伪多态很像
var Something {cool: function() {this.greeting Hello World;this.count this.count ? this.count 1 : 1;}
};Something.cool();
Something.greeting; // Hello World
Something.count; // 1
var Another {cool: function() {// 隐式把 Something 混入 AnotherSomething.cool.call( this );}
};
Another.cool();
Another.greeting; // Hello World
Another.count; // 1 count 不是共享状态通过在构造函数调用或者方法调用中使用 Something.cool.call( this )我们实际上“借用”了函数 Something.cool() 并在 Another 的上下文中调用了它通过 this 绑定。最终的结果是 Something.cool() 中的赋值操作都会应用在 Another 对象上而不是Something 对象上。 因此我们把 Something 的行为“混入”到了 Another 中。
5、总结
类是一种设计模式。许多语言提供了对于面向类软件设计的原生语法。JavaScript 也有类似的语法但是和其他语言中的类完全不同。
类意味着复制。
传统的类被实例化时它的行为会被复制到实例中。类被继承时行为也会被复制到子类中。
多态在继承链的不同层次名称相同但是功能不同的函数看起来似乎是从子类引用父类但是本质上引用的其实是复制的结。
JavaScript 并不会像类那样自动创建对象的副本。
混入模式无论显式还是隐式可以用来模拟类的复制行为但是通常会产生丑陋并且脆弱的语法比如显式伪多态OtherObj.methodName.call(this, …)这会让代码更加难懂并且难以维护。
此外显式混入实际上无法完全模拟类的复制行为因为对象和函数别忘了函数也是对象只能复制引用无法复制被引用的对象或者函数本身。忽视这一点会导致许多问题。
总地来说在 JavaScript 中模拟类是得不偿失的虽然能解决当前的问题但是可能会埋下更多的隐患。