Skip to content
Spotify - 每月低于 10 元

第6章 对象

创建对象

使用对象字面量创建对象

  • 当 value 是个变量且与 key 同名时,可简写
  • 有符号时,key 需要使用引号,且访问时只能通过obj['key']的方式访问
  • 方法可简写为 func() {}
js
let age = 18;

let obj = {
  name: '张三',
  age,
  sex: '男',
  'birth-data': '2020-01-01',
  sayHi: function () {
    console.log('hi~');
  },
  sayHello() {
    console.log('hello~');
  }
};

使用 new Object 创建对象

js
let obj = new Object();
obj.name = '张三';
obj.age = 18;
obj.sex = '男';
obj.sayHi = function () {
  console.log('hi~');
};

自定义构造函数

js
function People(name, age, sex) {
  this.name = name;
  this.age = age;
  this.sex = sex;
}

let zhangsan = new People('张三', 18, '男');

对象属性

概念

  • 每个对象里的键值对都是对象的属性
  • 如果键值对的值是函数,则把这个函数称作方法
js
let obj = {
  // 属性
  name: '张三',
  age: 18,
  sex: '男',
  'birth-data': '2020-01-01',
  // 方法
  sayHi: function () {
    console.log('hi~');
  }
};

访问对象属性

  • 方式一:obj.key
  • 方式二:obj['key']

遍历对象属性

  • 方式一:使用 Object.keys() 方法
  • 方法二:使用 for...in 方法
js
// 方式一
console.log(Object.keys(obj)); // [ 'name', 'age', 'sex', 'sayHi' ]

// 方法二
for (let key in obj) {
  console.log(key);
}

删除对象属性

  • 使用 delete 关键字
js
delete obj.name;
console.log(Object.keys(obj)); // [ 'age', 'sex', 'sayHi' ]

getters 与 setters

概念

  • JavaScript 中的 get、set 方法与 Java 等语言中的不同
  • JavaScript 中通过访问属性的方式进行使用,而不是 get() set() 类似 Vue 中的计算属性

字面量创建的对象

js
let person = {
  firstName: '三',
  lastName: '张',
  get fullName() {
    return this.lastName + this.firstName;
  },
  // setters只能接受一个参数
  set fullName(fullName) {
    let [lastName, firstName] = fullName.split(' ');
    this.firstName = firstName;
    this.lastName = lastName;
  }
};

console.log(person.fullName); // 张三
person.fullName = '李 四';
console.log(person.fullName); // 李四

构造函数创建的对象

js
function People(name, position) {
  this.name = name;
  this.position = position;
}

let people = new People('张三', 'CEO');

Object.defineProperty(people, 'info', {
  get: function () {
    return this.name + ' ' + this.position;
  },
  set: function (info) {
    let [name, position] = info.split(' ');
    this.name = name;
    this.position = position;
  }
});

console.log(people.info); // 张三 CEO
zhangsan.info = '李四 CFO';
console.log(people.info); // 李四 CFO

扩展运算符

在对象中使用

js
let post = {
  id: 1,
  title: '标题1',
  content: '这是内容'
};

console.log(post); // { id: 1, title: '标题1', content: '这是内容' }

let postClone = {
  ...post, // 将post中的所有属性复制过来
  author: '只抄'
};
console.log(postClone); // { id: 1, title: '标题1', content: '这是内容', author: '只抄' }

在数组中使用

js
let arr = [1, 2, 3];
let arrClone = [...arr, 4];
console.log(arrClone); // [1, 2, 3, 4]

在函数中使用

js
function savePost(id, title, content) {
  console.log(id, title, content);
}
// 这个数组会 Spread 成三个变量
savePost(...[1, '标题', '内容']); // 1 标题 内容

解构赋值

常规用法

  • 变量名需与属性名相同,需要别名时,使用冒号
  • 需要默认值时,使用等号
js
let post = {
  id: 1,
  title: '标题1',
  content: '这是内容'
};
let { id, title: headline, content, comments = '没有评论' } = post;
console.log(id, headline, content, comments); // 1 标题1 这是内容 '没有评论'

解构复杂对象、数组

js
let post = {
  id: 1,
  title: '标题',
  content: '这是内容',
  comments: [
    { userId1: 1, comment: '评论1' },
    { userId1: 2, comment: '评论2' },
    { userId1: 3, comment: '评论3' }
  ]
};

// 解构评论2
let {
  comments: [, { comment }]
} = post;

console.log(comment); // 评论2

动态 key

js
function getId(idKey, obj) {
  let { [idKey]: id } = obj; // 使用 [] 包裹 key
  return id;
}

console.log(getId('userId', { userId: 3 })); // 3

改变 this 的指向

默认情况

js
let people = {
  id: 1,
  name: '只抄',
  printInfo() {
    console.log('员工姓名:', this.name);
  },
  department: {
    name: '技术部',
    printInfo() {
      console.log('部门名称:' + this.name);
    }
  }
};
// this是点号左边的对象
people.printInfo(); // 员工姓名:只抄
people.department.printInfo(); // 部门名称:技术部

call & apply & bind

  • call & apply & bind 都可用于修改函数中this的指向
  • call & apply 使用后会立即执行函数
    • call 传参直接跟在后面
    • apply 传参需要使用数组
  • bind 使用后会返回一个新的函数
    • bind 传参同 call
js
function printInfo(age, sex) {
  console.log('员工姓名:', this.name);
  console.log('年龄:', age);
  console.log('性别', sex);
}

printInfo(18, '男'); // 员工姓名:undefined 年龄:18 性别 男
printInfo.call(people, 18, '男'); // 员工姓名:只抄 年龄:18 性别 男
printInfo.apply(people, [18, '男']); // 员工姓名:只抄 年龄:18 性别 男

let newPrintInfo = printInfo.bind(people, 18, '男');
newPrintInfo(); // 员工姓名:只抄 年龄:18 性别 男

继承

构造函数

  • 继承属性:子类构造函数中调用父类构造函数,并改变 this 指向
  • 继承方法:子类的 prototype 指向父类的实例对象 new Father()
js
function Father(uname) {
  this.uname = uname;
}

Father.prototype.sayHi = function () {
  console.log('hi~');
};

function Son(uname, age) {
  Father.apply(this, arguments); // 第1步
  this.age = age;
}

Son.prototype = new Father(); // 第2步(组合继承)

Son.prototype = Object.create(Father.prototype); // 第2步(寄生组合继承)
Son.prototype.constructor = Son; // 第2步(寄生组合继承)

const son = new Son('xiaowang', 15);
son.sayHi(); // hi~

对象

  • 使用 Object.create() 方法
  • Object.create() 会将原对象作为新对象的 prototype
js
let father = {
  uname: 'father'
};

let son = Object.create(father);
son.name = 'son';
son.age = 18;

// Object.getOwnPropertyNames(obj) 可用于查看自身的属性
console.log(Object.getOwnPropertyNames(son)); // ['name', 'age']
console.log(son.__proto__ === father); // true

原型 & 原型链

基本概念

  • prototype:函数的一个属性,它的作用是获取该函数的 prototype
  • __proto__:对象的一个属性,它的作用是指向所属构造函数的 prototype
  • 注意:函数都是由 Function 原生构造函数创建的,所以函数的 __proto__ 属性指向 Function 的 prototype 属性

原型

  • 构造函数有一个原型对象称作 prototype
  • 通过 prototype 属性可以向对象添加属性和方法
  • 实例对象会可以使用构造函数与原型对象中的属性和方法
js
function Father(uname, position) {
  this.name = uname;
  this.position = position;
  this.signIn = function () {
    console.log(this.name + '打卡');
  };
}

let father = new Father('father', '父亲');

Father.prototype.age = 18;
console.log(father.age); // 18

原型链

  • 原型链是指每个对象的原型还有上层的原型,直到 null
  • JavaScript 顶层对象是 Object,Object 原型的原型为 null,达到原型链顶端
  • 可以理解为原型链通过__proto__属性链接起来
  • obj.__proto__也可以写作 Object.getPrototypeOf(obj)
js
console.log(father.__proto__ === Father.prototype); // true
console.log(Father.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__ === null); // true

console.log(Object.getPrototypeOf(father) === Father.prototype); // true

图解

关注微信公众号RackNerd - 美国 163 直连线路
你认为这篇文章怎么样?
  • 0
  • 0
  • 0
  • 0
  • 0
  • 0

预览:

评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v3.1.3