[JS-10] JavaScript 对象

对象

什么是对象?
对象就是一系列属性的集合,一个属性包含一个名和一个值。

面向对象基本概念:

  • 类:类是对象的类型模板,比如定义 Dog 类表示狗,但不表示具体某只狗;
  • 实例:实例是根据类创建的对象,比如根据 Dog 可以创建出 aHuangdaHuamaoMao 等每个具体的狗。

在 JavaScript 中没有类这个类型,这一切都是通过原型(prototype)来实现的。

每一个 JavaScript 对象(null除外)都和另一个对象相关联。“另一个”对象就是原型,每一个对象都从原型继承属性。
所用通过对象直接量和 new Object() 创建的对象都具有同一个原型对象,可以通过 Object.prototype 获得对原型对象的引用。
同理,通过 new Data() 创建的对象的原型就是 Date.prototype
Data.prototype 的属性继承自 Object.prototype,而由 new Data() 创建的对象,属性同时继承自前两者,这一系列链接的原型对象就是:“原型链
注意 Object.prototype 是没有原型的。

创建对象

  • 对象直接量
  • 构造函数
  • Object.create()
// 对象直接量创建对象
var obj = {};

// 通过 new 创建
var obj = new Object();

// 通过 Object.create() 创建
var obj = Object.create({})

属性的操作

获取属性和改变属性

  • 通过 . 获取
  • 通过 [] 获取([]内必须是一个计算结果为字符串的表达式)

删除属性

  • delete
var obj = {
  name: 'huang',
  legs: 4,
  color: 'yellow'
}
console.log(obj.legs);   // 4

delete obj.legs;

console.log(obj.legs);   // undefined

检测属性

  • in 检测对象中是否包含此属性
  • hasOwnProperty() 检测该属性是否为对象的自有属性
  • propertyIsEnumerable() 检测该自有属性是否可枚举
var o = { x: 1 }

'x' in o;   // true
'y' in o;   // false
'toString' in o;   // true 继承自 Object.prototype

o.hasOwnProperty('x');   // true
o.hasOwnProperty('y');   // false
o.hasOwnProperty('toString');   // false

Object.prototype.propertyIsEnumerable('toString');   // false

枚举属性

  • for...in 依次访问一个对象及其原型链中所有可枚举的属性
  • Object.keys() 返回一个对象自身包含(不包括原型中)的所有属性的名称的数组
  • Object.getOwnPropertyNames() 返回一个数组,它包含了对象所有拥有的属性(无论是否可枚举)的名称

配置属性

  • configurable 配置能否修改或删除属性
  • enumerable 配置是否可枚举属性
  • value 指定属性的值
  • writable 是否可通过赋值语句修改属性值(读写/只读)
  • get 定义 getter 函数,当访问属性时调用,不能与 valuewritable 同时使用
  • set 定义 setter 函数,当对属性赋值时调用,不能与 valuewritable 同时使用

配置方法:

  • Object.defineProperty() 给对象添加一个属性并指定该属性的配置
  • Object.defineProperties() 给对象添加多个属性并分别指定它们的配置
var obj = {};

// 添加一个不可枚举的属性x,并赋值1
Object.defineProperty(obj, 'x', {
  value: 1,
  writable: true,
  enumerable: false,
  configurable: true
})

obj.x;   // 1
Object.keys(obj);   // []

obj.x = 2;   // 2

通过设置 setget 控制属性(可读写/只读/只写)

同时存在 setget 时,属性可读写
只有 set 时,属性值只能写入
只有 get 时,属性值只能读取

var obj = {
  data: 1,
  get r() {
    return this.data;
  },
  set r(val) {
    this.data = val;
  }
}

obj.data   // 1
obj.r   // 1
obj.r = 2;   // 2
obj.data   // 2

constructor 属性

引用当前对象的构造函数

ES6中对象属性初始值简写

// ES5中
function createPerson(name, age) {
  return {
    name: name,
    age: age
  }
}

// ES6中
function createPerson(name, age) {
  return {
    name,
    age
  }
}
// ES5中
var person = {
  name: 'Gala',
  sayName: function() {
    console.log(this.name);
  }
}

// ES6中
var person = {
  name: 'Gala',
  sayName() {
    console.log(this.name);
  }
}

Class

ECMAScript 2015 中引入的 JavaScript 类实质上是 JavaScript 现有的基于原型的继承的语法糖。类语法不会为JavaScript引入新的面向对象的继承模型。

类声明

class Person {
  constructor(name) {
    this.name = name;
  }

  sayName() {
    console.log(this.name);
  }
}

以上代码,相当于

function Person(name) {
  this.name = name;
}

Person.prototype.sayName = function() {
  console.log(this.name);
}

函数声明和类声明之间的一个重要区别是函数声明会提升,类声明不会。

let p = new Person();   // ReferenceError

class Person() {}

类表达式

// 匿名类
let Person = class {
  constructor(name) {
    this.name = name;
  }

  sayName() {
    console.log(this.name);
  }
}

// 命名的类
let Person = class Person {
  constructor(name) {
    this.name = name;
  }

  sayName() {
    console.log(this.name);
  }
}

方法定义

class Rectangle {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }

  // Getter
  get area() {
    return this.calcArea();
  }

  // Method
  calcArea() {
    return this.height * this.width;
  }
}

const square = new Rectangle(10, 20);
console.log(square.area);   // 200

可计算成员名称

let methodName = 'sayName';

class Person {
  constructor(name) {
    this.name = name;
  }

  [methodName]() {
    console.log(this.name);
  }
}

let p = new Person('gala');
p.sayName();   // 'gala'

也可以使用到 gettersetter 方法上。

静态方法

class Person {
  constructor(name) {
    this.name = name;
  }

  sayName() {
    console.log(this.name);
  }

  static create(name) {
    return new Person(name);
  }
}

let p = Person.create('gala');
// ES5中
function Person(name) {
  this.name = name;
}

// 静态方法
Person.create = function(name) {
  return new Person(name);
}

// 实例方法
Person.prototype.sayName = function() {
  console.log(this.name);
}

var p = Person.create('gala');

继承与派生类

class Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(this.name + ',叫~');
  }
}

class Dog extends Animal {
  constructor(name, color) {
    super(name);   // 调用原型上的方法,初始化this
    this.color = color;
  }
  speak() {
    console.log(this.color + '色的' + this.name + ',汪~')
  }
}

let aHuang = new Dog('阿黄', '黄');
aHuang.speak();   // 黄色的阿黄,汪~
// ES5中
function Animal(name) {
  this.name = name;
}

Animal.prototype.speak = function() {
  console.log(this.name + ',叫~');
}

function Dog(name, color) {
  Animal.call(this, name);
  this.color = color;
}

Dog.prototype.speak = function() {
  console.log(this.color + '色的' + this.name + ',汪~');
}
Dog.prototype.constructor = Dog;

var aHuang = new Dog('阿黄', '黄');
aHuang.speak();   // 黄色的阿黄,汪~

序列化对象

什么是JSON?

  • JSON.parse() 解析JSON字符串并返回对应的值
  • JSON.stringify() 返回与指定值对应的JSON字符串

JSON参考

你可能感兴趣的:([JS-10] JavaScript 对象)