js说:这就是对象

吐槽君 分类:javascript

在js中,对象究竟是个什么东西,这一章我们一起来学习

1、什么是对象

对象就是一个具体的事物

  • 明星不是对象,但是林俊杰是,周杰伦是,汪苏泷也是
  • 食物不是对象,但是北京烤鸭是,佛跳墙是,红烧狮子头也是

在js中,对象是一组无序的相关属性方法的集合,所有事物都是对象,如数值(Number)、字符串(String)、数组(Array)、函数(Function)等

对象(Object)是复杂数据结构

对象由属性和方法组成:

  • 属性:事物的特征,在对象中用属性来表示(常用名词)
  • 方法:事物的行为,在对象中用方法来表示(常用动词)

人.png

2、创建对象的三种方法

在js中,我们有三种方式可以创建对象(object):

  1. 利用 字面量 创建对象
  2. 利用**new Object()** 创建对象
  3. 利用 构造函数 创建对象

2.1 利用字面量创建对象

对象字面量:{},花括号包含了表达这个对象的属性和方法

先来看看:

var obj = {
    name: '老林',
    age: 18,
    sayHi: function() {
        console.log('你好hhhh');
    }
}

// 调用属性
console.log(obj.name);  // 老林
console.log(obj.age);  // 18
// 调用方法
obj.sayHi();  // 你好hhhh
 
  1. 在对象里面的属性和方法我们采用键值对的形式
  2. 调用属性和方法:对象名.属性值对象名[属性值]
  3. 对象里面的函数就是方法,方法不需要声明,使用 对象.方法名() 方式就可以调用
  4. 属性名可以是字符串或者是数值(提示:对象会自动把属性转换为字符串

比较流行的写法

2.2 利用 new object 创建对象

语法格式:

var 对象名 = new Object();
 

让我们来看看:

// 先创建一个空对象
var obj = new Object()
// 再往对象里面装东西
obj.name = '老林'
obj.age = 18
obj.sayHi = function() {
    console.log('你好hhhh');
}

// 打印对象
console.log(obj); // { name: '老林', age: 18, sayHi: [Function (anonymous)] }
console.log(obj.name);  // 老林
console.log(obj.sayHi());  // 你好hhhh
 

这种方式创建的obj对象与上面利用字面量创建的对象一样

2.3 利用构造函数创建对象

像两种创建对象的方法一次只能创建一个对象,如果我们先创建多个对象,有什么办法呢?

答案就是函数,前面我们说过函数就是封装一段代码让我们可以重复调用,在这里我们可以利用函数来重复这些相同的代码,这里有一种专业做个的函数,我们把这个函数叫作的构造函数

构造函数就是一种特殊的函数,主要用来初始化对象,即为对象的成员变量赋值。它总是与new运算符一起使用,把我们对象里面的一些相同的属性和方法封装到这个函数里面

让我们来感受一下它的威力:

// 构造函数
function Person(name, age) {
    this.name = name;
    this.age = age;
    this.sing = function(song) {
        console.log(this.name + '的' + song);
    }
}

// 创建对象
var person1 = new Person('老林', 18)
console.log(person1.name); // 老林
person1.sing('江南'); // 老林的江南

// 创建对象
var person2 = new Person('汪苏泷', 18)
console.log(person1.age); // 18
person2.sing("有点甜"); // 汪苏泷的有点甜
 
  1. 构造函数首字母要大写
  2. 构造函数里面不需要return,直接返回结果
  3. 调用构造函数,必须使用new

所以,对象和构造函数之间是什么关系?

  • 构造函数就是泛指某一类,如:明星、食物
  • 对象就是具体的某一个事物,如:老林、汪苏泷

利用构造函数创建对象的过程就是对象的实例化


new 关键字

new 在执行的时候回做的四件事:

  1. 子内存中创建衣蛾新的空对象
  2. this 指向这个新对象
  3. 执行函数里面的代码,给对象添加属性和方法
  4. 返回这个新对象(所以构造函数里面不需要 return

3、遍历对象属性

for...in 语句用于对数组或者对象的属性进行循环操作

var person = {
    num: 2,
    year_: 2020
}

for (var key in person) {
    console.log(key + ':' + person[key]);
}

// num:2
// year_:2020
 

4、获取对象的长度

获取对象的长度有3种方式:

  1. Object.keys[对象].length
  2. 遍历对象属性,计算属性的个数
  3. Object.getOwnPropertyNames(obj).length

4.1 Object.keys[对象].length

Object.keys[对象] 返回包含对象属性的列表

var person = {
    num: 2,
    year_: 2020
}
console.log(Object.keys(person).length);  // 2
 

4.2 遍历

var k = 0
for (var i in person) {
    k++
}
console.log(k);  // 2
 

4.3 Object.getOwnPropertyNames(对象)

Object.getOwnPropertyNames() : 获取对象属性

console.log(Object.getOwnPropertyNames(person).length);  // 2
 

5、对象属性

对象的属性分为两种:数据属性访问器属性

这两个属性就是用来约束对象里的属性和方法的

5.1 数据属性

数据属性.png

前3个属性都是被默认为 true

什么意思?

当我们的定一个对象的时候,默认就是我们可以:

  • 使用delete删除属性和方法
  • 对象默认可以被遍历
  • 对象属性的属性值和方法默认是可以被修改的

要修改属性的默认值,需要使用 Object.defineProperty() 方法

语法:

// 接收3个参数
Object.defineProperty(属性所在的对象, 要修改的属性, 一个描述符对象)
 

下面就来试一下:

var person = {
    name: '老林',
    age: 18,
    hobby: '唱歌, 吉他'
}

Object.defineProperty(person, 'name', {
        configurable: false,  // 禁止删除
        enumerable: false,  // 禁止该项被遍历,被隐藏了,但是可以被访问
        writable: false,  // 禁止修改
        value: '老周'  // 给该属性赋值,禁止修改,只能在此处才能修改该属性
    })

delete person.name  // 无法删除
for (var k in person) {
    console.log(person[k]);  // 无法遍历到name属性
}
// 此处name只是被隐藏了,并不是被删除,还是可以别访问的
console.log(person); // { age: 18, hobby: '唱歌, 吉他' }
console.log(person.age); // 18
console.log(person.name); // 老周
 

注意:

  • 一个属性被定义为不可配置之后,就不能再修改回来了(configurable 不能改回 true了)

5.2 访问器属性

我们通常可以定义一个访问器属性,来操作对象里面的属性和方法

访问器属性不包含数据值,只定义行为

它同样拥有4个特性:

  • [[Configurable]]:表示是否可以通过delete删除并重新定义,以及是否可以把它修改为数据特性
  • [[Enumerable]]:表示属性书否可以被遍历
  • 获取函数getter:在读取访问器属性时,会调用该获取函数,这函数的作用就是返回一个有效的值
  • 设置函数setter:在写入访问器属性时,会调用设置函数并传入新值,这个函数必须决定对内部数据做出什么修改
var person = {
    num: 2,
    year_: 2020
}

// 定义一个访问器属性
Object.defineProperty(person, 'year', {
    // 获取属性值
    get() {
        return this.year_;
    },
    // 修改属性值
    set(newAge) {
        if (newAge > this.year_) {
            this.num = newAge - this.year_;
            this.year_ = newAge;
        }
    }
});

person.year = 2021
console.log(person.year_); // 2021
console.log(person.num); // 1
 

扩展:获取键值两种方式的区别

  • person.name
  • person[name]

这两种方式没有多大的区别,

  • 一般使用第一种;如果我们想要拼接键,就要采用第二种
  • 第一种一般是属性为字符串,当数值、布尔值用第二种
var obj = { x1: 1, x2: 2, x3: 3 }

for (var i = 1, k = Object.keys(obj).length; i <= k; i++) {
    console.log(obj['x' + i]);
}
// 1, 2, 3
 
var obj = {
    1: 'a',
    2: 'b',
    true: 'c'
}
console.log(obj[1]);  // a
console.log(obj.[true]);  // c
 

回复

我来回复
  • 暂无回复内容