美文网首页
面向对象的程序设计-对象

面向对象的程序设计-对象

作者: 婆娘漂亮生活安逸 | 来源:发表于2019-03-22 17:31 被阅读0次

写在前面的:需要大量时间反复理解;

《高程》中这么描述:
面向对象(Object-Oriented,OO)的语言有一个标志,那就是它们都有类的概念,而通过类可以创建任意多个具有相同属性和方法的对象。前面提到过,ECMAScript中没有类的概念,因此它的对象也与基于类的语言中的对象有所不同。 ECMA-262把对象定义为:无序属性的集合,其属性可以包含基本值、对象或者函数。”严格来讲,这就相当于说对象是一组没有特定顺序的值。对象的每个属性或方法都有一个名字,而每个名字都映射到一个值。正因为这样,我们可以把ECMAScript的对象想象成散列表:无非就是一组名值对,其中值可以是数据或是函数。

1. 理解对象

1.1 属性类型 ECMAScript中有两种属性:数据数据和访问器属性

  • 数据属性
描述数据属性行为的特性 功能
[[Configurable]] 能否通过delete 删除,能否修改属性特性,能否把属性修改为访问器属性
[[Enumerable]] 能否通过 for-in 循环返回属性
[[Writable]] 能否修改属性值
[[Value]] 属性的数据值

修改属性默认的特性,必须使用 Object.defineProperty(),该方法接受三个参数:属性所在的对象,属性的名字,描述对象(只能为configurable,enumerable,writable , value)。

var person = {};
Object.defineProperty(person, 'name', { writable: false, value: 'Maning'});
console.log(person.name); // Maning
person.name = 'Other';
console.log(person.name);  // Maning

该例创建一个名为name属性,值为只读,这个属性的值是不可修改的,重新赋值后,并未成功。
var person = {};
Object.defineProperty(person, 'name', { configurable: false, value: 'Maning'});
console.log(person.name,1);    // Maning
person.name = 'Other';  
console.log(person.name,2); // Maning
delete person.name;    
console.log(person.name, 2);    // Maning

设置configurable为false后,定义属性为不可配置的,主要表现有以下:
不能从对象中删除属性;
不能去修改属性值;
其余三个属性默认值均为false。
更简洁的说,除了能再次修改writable的属性,其余属性均无法修改。
  • 访问器属性
描述访问器属性的特性 功能
[[Configurable]] 能否通过delete 删除,能否修改属性特性,能否把属性修改为访问器属性
[[Enumerable]] 能否通过 for-in 循环返回属性
[[Get]] 读取属性调用的函数
[[Set]] 写入属性调用的函数

2. 创建对象

2.1 工厂模式

// 本例来源《高程》
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 person1 = createPerson("Nicholas", 29, "Software Engineer");
var person2 = createPerson("Greg", 27, "Doctor");

每个实例对象虽然通过同一个方法出来,但是全部是通过Object实例化出来,即使传入的参数完全相同的情况,其实两者也是不等的。

2.2 构造函数模式

function Person(name, age, job){
        this.name = name;
        this.age = age;
        this.job = job;
        this.sayName = function(){
            alert(this.name);
}; }
var person1 = new Person("Nicholas", 29, "Software Engineer");
var person2 = new Person("Greg", 27, "Doctor");

该方式创建对象,我们能够看到以下几点不同:
1.没有显示创建对象,
2.直接将属性和方法赋给了this对象,
3.没有return语句
4.函数名的首字母是大写(这应该是一种规范,区分与其他函数)

  • 构造函数当作函数使用
// 当作构造函数使用
var person = new Person("Nicholas", 29, "Software Engineer"); 
person.sayName(); //"Nicholas"

// 普通函数
// 在全局作用域中调用函数,this对象指向Global对象(在浏览器指向window)
Person("Greg", 27, "Doctor"); 
window.sayName(); //"Greg"

// 另一个对象的作用域中调用
var o = new Object();
Person.call(o, "Kristen", 25, "Nurse"); o.sayName(); //"Kristen"
  • 构造函数问题
    每一个方法都要在每一个实例上重新创建,这就意味着每一个实例的同名方法其实是不等价的,因为它们都是不同的实例。
    解决方法:可以让构造函数中的方法指向同一个全局函数,但这又带来另外的问题,如果多个方法则会暴露出多个全局函数。

2.3 原型模式

💡请理解《高程》中的这么一句话:我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。

 function Person(){
 }
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
    alert(this.name);
};
var person1 = new Person();
person1.sayName();   //"Nicholas"
var person2 = new Person();
person2.sayName(); //"Nicholas"
alert(person1.sayName == person2.sayName);  //true
  • 理解原型

1.只要创建一个新函数,该函数会有一个prototype(原型)属性,去指向一个原型对象,包含所有共享属性与方法。
2.所有原型对象会有一个constructer(构造函数)属性,指向构造函数。
3.原型对象方法isPrototypeOf()来确定对象之间的关系:
Person.prototype.isPrototypeOf(person1) // true
4.ES5方法Object.getPrototypeOf()返回原型对象值;
Object.getPrototypeOf(person1) // { ... }
5.如果实例中添加一个与原型同名的属性时,原型的属性不会被修改,但只能访问到实例的属性;只有使用delete删除实例属性,才能重新访问原型属性。
6.hasOwnProperty()检测一个属性是否存在于实例中;
person1.hasOwnProperty( "name")

2.4 组合模式构造函数模式和原型模式

顾名思义,采用构造函数模式定义实例属性,原型模式定义方法和共享的属性。这样子每个实例有各自的实例属性副本,又共享对方法的引用,最大限度节省了内存。

function Person(){
}
Person.prototype = {
    constructor: Person,
    name : "Nicholas",
    age : 29,
    job : "Software Engineer",
    friends : ["Shelby", "Court"],
    sayName : function () {
        alert(this.name);
} };
var person1 = new Person();
var person2 = new Person();
person1.friends.push("Van");
alert(person1.friends);    //"Shelby,Court,Van"
alert(person2.friends);    //"Shelby,Court,Van"
alert(person1.friends === person2.friends);  //true

⚠️以下几种不做过多描述,想要了解,可以参考《高程》第6章第6.2节

2.5 动态原型模式

根据需要判断是否要初始化原型;

2.6寄生构造函数模式

在构造函数中返回一个实例化的对象;

2.7妥协构造函数模式

主要提供安全性;

相关文章

  • 《软件工程》笔记7

    面向对象的实现 面向对象的程序设计最好还是选用面向对象的编程语言。 良好的程序设计风格对于面向对象实现来说格外重要...

  • 《Java核心技术卷 I》之 Java对象与类

    Java对象与类 面向对象程序设计 面向对象程序设计,简称OOP,Java语言就是完全面向对象的。 类 类(cla...

  • JavaScript面向对象编程指南--读书笔记(上)

    第一章:面向对象的JavaScript 面向对象的程序设计 面向对象程序设计(oop)中最常用到的概念: 对象、方...

  • 面向对象

    title:面向对象tags: 基础,Java 面向对象 面向对象程序设计简介 面向对象的基本思想是使用类、对象、...

  • 第四章 对象与类

    1 面向对象程序设计概述 面向对象程序设计(简称OOP)是当今主流的程序设计范型 Java是完全面向对象的,必须熟...

  • oc编程思想

    面向对象概念 面向对象编程(Object Oriented Programming,OOP,面向对象程序设计)是一...

  • C#之对象

    对象的定义 对象(Object)是面向对象的程序设计的核心,世界万物皆对象。因此可以说面向对象的程序设计,实质是用...

  • 对象与类

    对象与类 Tags: Java核心技术卷I 面向对象程序设计概述 面向对象程序设计简单OOP。 类类是构造对象的模...

  • 「JS」面向对象

    面向对象程序设计方法面向过程面向对象概念基本特点 JavaScript 面向对象constructor自定义构造器...

  • JavaSE-面向对象编程

    [TOC] 第一章:面向对象-概述 1.1-什么是面向对象? 概述 面向对象是一种程序设计思想。 程序设计的目的是...

网友评论

      本文标题:面向对象的程序设计-对象

      本文链接:https://www.haomeiwen.com/subject/lwenmqtx.html