一、对象是什么?对象的特征?
个人理解:描述程序世界的一种方式,一种数据结构。
- 具有唯一标志性:即使完全相同的两个对象,也并非同一个对象(引用类型);
- 有状态:同一对象可能处于不同状态下;
- 有行为:对象的状态可能因为它的行为产生变迁。
二、面向对象是什么?
面向对象编程是用抽象方式创建基于现实世界模型的一种编程模式。每个对象能够接收消息,处理数据和发送消息给其他对象。每个对象都可以被看作是一个拥有清晰角色或责任的独立小机器。目的是在编程中促进更好的灵活性和可维护性。宿主和语言的基础设施由对象来提供,程序既是一系列互相通讯的对象集合。
三、面向对象的特点
抽象:把核心的东西抽出来,把与我们要解决的问题有关的东西拿出来摆在面前;
封装:不考虑内部实现,只考虑功能使用,把内部的代码保护起来,只留出一些个api接口供用户使用;
继承:为了代码的复用,从父类上继承出一些方法和属性,子类也有自己的一些属性;
多态:不同对象作用于同一操作产生不同的结果。
四、js中的面向对象
JavaScript中对象独有的特色:对象具有高度的动态性,这是因为JavaScript赋予了使用者在运行时为对象添改状态和行为的能力
一、原型
- 所有的引用类型(对象、数组、函数)都有一个 _proto_ 属性,值是一个对象;
- 所有函数都有一个 prototype 属性,值是一个对象;
- 引用类型的 _proto_ 属性值指向它的构造函数的 prototype 属性值;
二、创建对象
// 构造函数
function Person(name, age) {
this.name = name;
this.age = age;
}
var p1 = new Person('Jack', 20);
// 字面量
var o = {}
三、继承的几种实现方法
// 1-原型链继承
function SuperType(name){
this.name = name;
this.colors = ['pink', 'blue', 'green'];
}
function SubType(){
this.age = 22
}
SubType.prototype = new SuperType()
SubType.prototype.constructor = SubType
let type1 = new SubType();
type1.colors.push('yellow');
console.log(type1.colors); //["pink", "blue", "green", "yellow"]
let type2 = new SubType();
console.log(type2.colors); //["pink", "blue", "green", "yellow"]
缺点:原型为另一个类型的实例,原先的实例属性变成了现在的原型属性,该原型的引用类型属性会被所有的实例共享。
// 2-构造函数继承
function SuperType(name){
this.name = name;
this.colors = ['pink', 'blue', 'green'];
}
function SubType(name){
SuperType.call(this, name);
}
let type1 = new SubType('rose');
type1.colors.push('yellow');
console.log(type1.colors); //["pink", "blue", "green", "yellow"]
let type2 = new SubType('jack');
console.log(type2.colors); //["pink", "blue", "green"]
优点:解决了原型中包含引用类型值被所有实例共享的问题
缺点:方法都在构造函数中定义,函数复用无从谈起,另外超类型原型中定义的方法对于子类型而言都是不可见的。
// 3-组合继承
function SuperType(name){
this.name = name;
this.colors = ['pink', 'blue', 'green'];
}
function SubType(name, age){
SuperType.call(this, name);
this.age = age;
}
SubType.prototype = new SuperType()
SubType.prototype.constructor = SubType
let type1 = new SubType('rose', 22);
type1.colors.push('yellow');
console.log(type1.colors); //["pink", "blue", "green", "yellow"]
let type2 = new SubType('jack', 22);
console.log(type2.colors); //["pink", "blue", "green"]
缺点:无论什么情况下,都会调用两次超类型构造函数:一次是在创建子类型原型的时候,另一次是在子类型构造函数内部。
优点:每个实例都有自己的属性,可以向超类传递参数,实现了函数复用。
// 4-原型式继承 等同于只传入一个参数的Object.create()
function object(o){
function F(){}
F.prototype = o
return new F()
}
缺点:包含引用类型值的属性会被所有实例共享
// 5-寄生式继承
function createAnother(original){
var clone = Object.create(original)
clone.sayHi = function(){
console.log('hi')
}
return clone
}
缺点:不能复用函数,包含引用类型值的属性会被所有实例共享。
// 6-寄生组合式继承
function inheritPrototype(SubType, SuperType){
var temp = Object.create(SuperType.prototype)
temp.constructor = SubType
SubType.prototype = temp
}
function SuperType(name){
this.name = name
this.colors = ['pink', 'blue', 'green']
}
function SubType(name, age){
SuperType.call(this, name)
this.age = age
}
inheritPrototype(SubType, SuperType)
let type1 = new SubType('rose', 22);
type1.colors.push('yellow');
console.log(type1.colors); //["pink", "blue", "green", "yellow"]
let type2 = new SubType('jack', 22);
console.log(type2.colors); //["pink", "blue", "green"]
优点:只调用了一次超类构造函数,效率更高。同时能保持原型链不变。
// 7-class继承
class SuperType{
constructor(name){
this.name = name
}
getName() {
console.log(this.name)
}
}
class SubType extends SuperType{
constructor(name, age){
super(name)
this.age = age
}
getAge() {
console.log(this.age)
}
}
let instance = new SubType('kiko', 22)
instance.getName() // kiko