JavaScript中的对象、类与面对对象编程

本文深入探讨JavaScript中的对象创建、属性类型、继承机制以及类的概念。介绍了如何通过Object()构造函数、对象字面量创建对象,详细解析了数据属性和访问器属性。进一步讲解了工厂模式、构造函数模式、原型模式等对象创建模式以及组合继承、原型式继承等继承方式。最后,讨论了ES6中的class关键字及其在继承中的应用。
摘要由CSDN通过智能技术生成

1.理解对象

在ECMA-262中将对象定义为一组无序组合。对象的每个属性或方法都由一个名称来标识,这个名称映射到一个值,值可以是数据或者函数。创建自定义对象就是使用**Object()**函数

let person = new Object();
person.name = 'meta';
person.age = 23;
person.sayName = function () {
    console.log(this.name);
}

也可以使用对象字面量来创建对象

let person = {
    name = 'meta',
    age = 23,
    sayName = function () {
        console.log(this.name)
    }
};

对象属性的类型

数据属性
/*Configurable : 属性是否可用delete删除并重新定义,是否可修改特性,是否可改为访问器属性
Enumerable : 属性是否可用for-in循环返回
Weitable : 属性是否可被修改
Value : 属性的值*/
let person = {};
Object.defineProperty(person, "name", {
    configurable: true,
    enumerable: false,
    writable: true,
    value: 'meta'
});
console.log(person.name)
//meta
访问器属性
/*Configurable:属性是否可用delete删除并重新定义,是否可修改特性,是否可改为访问器属性
Enumerable:属性是否可用for-in循环返回
Get:获取函数,在读取属性时调用
Set:设置函数,在写入属性时调用*/
let person = {
    id_: '10001'
};
Object.defineProperty(person, "id", {
    configurable: true,
    enumerable: false,
    get() {
        return this.id_;
    },
    set(name) {
        this.id_ = name;
    }
});
console.log(person.id);
person.id = '10002';
console.log(person.id);
//_常用来表示该属性并不希望在对象方法的外部被访问到
同时定义多个属性
let person = {};
Object.defineProperties(person, {
    id_: {
        value: '10001'
    },
    name: {
        value: 'meta'
    },
    id: {
        get() {
            return this.id_
        },
        set(id) {
            this.id_ = id
        }
    }
});
console.log(person.id, person.name)
//10001 meta
获取属性特性
let person = {};
Object.defineProperty(person, "name", {
    configurable: true,
    enumerable: false,
    writable: true,
    value: 'meta'
});
let descriptor = Object.getOwnPropertyDescriptor(person, "name");
console.log(descriptor);
/*
{
  value: 'meta',
  writable: true,
  enumerable: false,
  configurable: true
}
*/
对象解构
let person = {
    name: 'meta',
    id: '10001'
};
let { name, id } = person;
let { name: personName, id: personId } = person;
console.log(name, id, personName, personId);
//meta 10001 meta 10001

2.创建对象

虽然使用**Object()**构造函数或字面量可以方便的创建对象,但是这些方式也有明显的不足:创建具有相同接口的多个对象需要重复编写很多代码。

工厂模式
function createPerson(name, id) {
    let o = new Object();
    o.name = name;
    o.id = id;
    o.sayName = function () {
        console.log(this.name);
    }
    return o;
}
let p1 = createPerson('meta1', '10001');
let p2 = createPerson('meta2', '10002');
console.log(p1, p2);
//{ name: 'meta1', id: '10001', sayName: [Function (anonymous)] } { name: 'meta2', id: '10002', sayName: [Function (anonymous)] }
构造函数模式
function Person(name, id) {
    this.name = name;
    this.id = id;
    this.sayName = function () {
        console.log(this.name);
    }
}
let p1 = new Person('meta1', '10001');
let p2 = new Person('meta2', '10002');
console.log(p1, p2);
//Person { name: 'meta1', id: '10001', sayName: [Function (anonymous)] } Person { name: 'meta2', id: '10002', sayName: [Function (anonymous)] }
原型模式
function Person() { };
Person.prototype.name = 'meta';
Person.prototype.id = '10001';
Person.prototype.sayName = function () {
    console.log(this.name);
};
let p1 = new Person();
let p2 = new Person();
p1.sayName();
p2.sayName();
//meta
//meta

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.prototype.sayAge = function () {
  console.log(this.age);
};

let instance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
console.log(instance1.colors);  // "red,blue,green,black"
instance1.sayName();            // "Nicholas";
instance1.sayAge();             // 29

let instance2 = new SubType("Greg", 27);
console.log(instance2.colors);  // "red,blue,green"
instance2.sayName();            // "Greg";
instance2.sayAge();             // 27
原型式继承
function object(o) {
  function F() { }
  F.prototype = o;
  return new F();
}

let person = {
  name: "Nicholas",
  friends: ["Shelby", "Court", "Van"]
};

let anotherPerson = object(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");

let yetAnotherPerson = object(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie");
console.log(person.friends);   // "Shelby,Court,Van,Rob,Barbie"
寄生式继承
function object(o) {
    function F() { }
    F.prototype = o;
    return new F();
};
function createAnother(original) {
    let clone = object(original);
    clone.sayHi = function () {
        console.log('hi');
    }
    return clone;
};
let person = {
    name: "Nicholas",
    friends: ["Shelby", "Court", "Van"]
};
let anotherPerson = createAnother(person);
anotherPerson.sayHi()  //hi
寄生式组合继承
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);      // second call to SuperType()
  
  this.age = age;
}
           
SubType.prototype = new SuperType();   // first call to SuperType()
SubType.prototype.constructor = SubType;           
SubType.prototype.sayAge = function() {
  console.log(this.age);
};

4.类

在ES6中引入了class关键字具有正式定义类的能力。

类定义
// class declaration
class Person {}

// class expression
const Animal = class {};
类构造函数
class Animal {}

class Person {
  constructor() {
    console.log('person ctor');
  }
}

class Vegetable {
  constructor() {
    this.color = 'orange';
  }
}

let a = new Animal();

let p = new Person();  // person ctor

let v = new Vegetable();
console.log(v.color);  // orange
继承
class Vehicle {}

// Inherit from class
class Bus extends Vehicle {}

let b = new Bus();
console.log(b instanceof Bus);      // true
console.log(b instanceof Vehicle);  // true


function Person() {}

// Inherit from function constructor
class Engineer extends Person {}

let e = new Engineer();
console.log(e instanceof Engineer);  // true
console.log(e instanceof Person);    // true
ClassInheritanceExample01.js

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值