美文网首页
ES5-面向对象(Object-Oriented, OO)

ES5-面向对象(Object-Oriented, OO)

作者: zhaochengqi | 来源:发表于2018-06-05 18:35 被阅读58次

1. 对象

在JavaScript中,一个对象可以理解为一组无序属性的集合。每个对象都是基于一个引用类型创建的,引用类型的值(对象)是引用类型的一个实例。

2. 类

JavaScript并不具备传统OO语言所支持的类和接口等基本结构。ECMAScript中与类类似的是引用类型。《JavaScript高级程序设计》对引用类型是这样描述的:

引用类型是一种数据结构,用于将数据和功能组织在一起。它也常被称为类,但这种称呼并不妥当。虽然引用类型与类看起来相似,但他们并不是相同的概念。

创建对象的几种模式:

补充:记住这些模式名称可以大大提高沟通效率、加深对各种模式的优劣理解

  1. 工厂模式——创建工厂函数,封装了以特定接口创建对象的具体细节;但是没有解决对象识别问题
  2. 构造函数模式——解决了对象识别问题;但是每个方法都要在实例上重新创建一遍
  3. 原型模式——原型包含了实例共享的方法属性;
  4. 构造+原型——取长避短:)
function Person(name, age) {
  this.name = name;
  this.age = age;
}
Person.prototype = {
  constructor: Person,
  talk: function () {
    console.log('talking。。。')
  }
}

↓Attention↓

function Person(name, age) {
  this.name = name;
  this.age = age;
  //其实这种方式也不推荐,毕竟每次调用构造函数都会执行一次
  Person.prototype.speak = function(){}

  //不要在构造函数内部重置原型,此次创建的新实例已
  //经指向到‘类’的原型,而下列语句会重置'类'的原型。
  Person.prototype = {
    constructor: Person,
    talk: function () {
      console.log('talking。。。')
    }
  }
}
  1. 动态原型——把所有信息都封装在构造函数里(个人不太喜欢),不再在构造函数外设置原型;
function Person(){
  if(typeof this.smMtd != 'function'){
    Person.prototype.smMtd = function(){}
  }
}
  1. 寄生构造函数——创建一个函数用来封装创建对象的代码,然后返回新创建的对象;除了使用new操作符,和工厂模式是一毛一样的;同样存在对象识别问题
    如果不能修改现有构造函数,可以考虑这个模式:
function SpecialArray(){
  var a = new Array()
  a.push.apply(a, arguments)
  a.newMethod = function(){return ''}
  return a
}
var a = new SecialArray('a', 'b', 'c')
  1. 稳妥构造函数——创建稳妥对象(没有公共属性、不使用this;不使用new操作符);同样存在对象识别问题
/**
 * 这种模式创建的对象,除了使用sayName方法,没有其他方式可以访问数据成员
 * 传入构造函数的原始数据是安全的
*/
function Person(name){
  var o = new Object()
  o.sayName = function(){console.log(name)}
  return o;
}
var p = Person('Frank')
  1. Object构造函数/对象字面量——使用同一个接口创建很多对象会产生大量的重复代码。
var ob = new Object();

终极构造方案( ̄▽ ̄)/

var MyCls = (function(){
  //静态私有变量
  var i = 0
  //静态私有方法
  var l = function(){console.log('0.1')}
  //构造函数
  function _(p1, p2, p3){
    if(!(this instanceof _)){
      return new _(p1, p2, p3)
    }
    //私有变量
    var a, b, c
    //公有属性
    this.p1 = p1
  }
  _.prototype = {
    constructor: _,
    //静态公有变量
    v: 0.1
  }
  //对象无法访问的静态公有变量
  _.t = 0
return _
}());

扩展


属性类型

ES5描述了属性的各种特征,这些特性只有内部才使用。对象的属性(property)在创建时都带有一些特征值(characteristic),JavaScript通过这些特征值来定义它们的行为。ES5定义这些特性是为了实现JavaScript引擎用的,因此在JavaScript中不能直接访问它们。

ES中有两种属性:数据属性和访问器属性;

  • 要修改属性默认的特性,必须使用ES5的 Object.defineProperty(object, property, descriptor) 方法。在调用此方法 创建新的属性时,如果不指定特征值,configurable、enumerable和writable特性的默认值都是 false

  • 读取给定属性的描述符可以使用 Object.getOwnPropertyDescriptor(object, property)

  • 访问器属性不能直接定义,必须使用 defineProperty() 来定义。

数据属性:数据属性有4个特性,包含一个数据值的位置:

[[Configurable]]:能否 delete、修改属性特性、把属性修改为访问器属性。直接定义在对象上的属性此特征值默认为true
//注意 此特性标识 在对象上执行 for-in循环时,该属性是否会被返回
[[Enumerable]]:能否通过for-in 循环返回属性()。直接定义在对象上的属性此特征值默认为true
[[Writable]]:能否修改属性的值。直接定义在对象上的属性此特征值默认为true
[[Value]]:包含这个属性的数据值,读写都在这个位置。默认为undefined

访问器属性:访问器属性不包含数据值,但包含getter和setter函数(非必需)。其有4个特性:

[[Configurable]]:能否 delete、修改属性特性、把属性修改为数据属性。直接定义在对象上的属性此特征值默认为true
[[Enumerable]]:能否通过for-in 循环返回属性。直接定义在对象上的属性此特征值默认为true
[[Get]]:在读取属性时调用的函数,默认值为undefined
[[Set]]:在写入属性时调用的函数,默认值为undefined

eg.

var frank = {
  name: 'frank', 
  _age: 25, //下划线前缀是一种常用记号, 表示该变量应通过对象方法访问
  year: 2018
}
Object.defineProperty(frank, 'age', {
  get: function(){
    return this._age;
  },
  set: function(newValue) {
    this.year += newValue - this._age
    this._age = newValue
  }
});

Object.defineProperties

//定义/修改多个属性
var person = {};
Object.defineProperties(person,{
  _name: {
    writable: true,
    value: 'frank'
  },
  age: {
    
  }
});

Object.getOwnPropertyDescriptor

//取得给定属性的描述符对象
var propObj = Object.getOwnPropertyDescriptor(frank, 'name')
//propObj://{value: "frank", writable: true, enumerable: true, configurable: true}

Object.getOwnPropertyDescriptors

//取得对象所有属性的描述符
var propObj = Object.getOwnPropertyDescriptors(person)
//{name:{value: "frank", writable: true, enumerable: true, configurable: true}}

相关文章

  • ES5-面向对象(Object-Oriented, OO)

    1. 对象 在JavaScript中,一个对象可以理解为一组无序属性的集合。每个对象都是基于一个引用类型创建的,引...

  • java 相关单词(一)

    OO: object-oriented ,面向对象OOP: object-oriented programming...

  • Python9--面向对象编程

    1. 面向对象编程简介 面向对象程序设计(英语:Object-oriented programming,缩写:OO...

  • 换个角度,用OO看世界

    何宏伟 [嵌牛导读] OO,Object-Oriented,面向对象。对于将C++/Java这类具有面向对象特性语...

  • OOD与OOP的区别

    OOD:面向对象设计 面向对象设计(Object-Oriented Design,OOD)方法是OO方法中一个中间...

  • 理解对象以及属性

    什么是对象?面向对象(Object-Oriented,OO).ECMAScriptt没有类的概念,ECMA262把...

  • 第五天

    第五天-纠结的面向对象(Object-Oriented,OO) 今天直接进入了Java的面向对象的学习,面向对象是...

  • JavaScript高程读书笔记-面向对象设计

    一、理解对象 1、什么是对象面向对象(Object-Oriented,OO),ECMA中对象定义是:无序属性的集合...

  • 02.OOP面向对象-1.面向对象介绍

    1、面向对象编程介绍 面向对象(object-oriented ;简称: OO) 至今还没有统一的概念 我这里把它...

  • Python基础(六)

    面向对象编程介绍 面向对象(object-oriented ;简称: OO) 至今还没有统一的概念,我这里把它定义...

网友评论

      本文标题:ES5-面向对象(Object-Oriented, OO)

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