对象的创建以及显示转换

目录

 单个对象的创建

对象的访问

遍历对象

 删除对象属性

 显示类型转换

检测属性

Object原型属性及方法(原型方法,实例可以调用的方法)

深入理解对象-定义属性

对象序列化


 单个对象的创建
1. 字面量 var obj={}
2. 构造函数  var obj=new Object()

对象的访问
1. 点访问  obj.name
2. 中括号访问 obj['age']


遍历对象

for(var key in obj){
key----键 属性名
obj[key]-----值 属性值
}


 

 删除对象属性
delete obj.name


 显示类型转换

  •  Object类型到Boolean类型

除了空引号(null)会转换为false,其它都被转换成true

var obj = null
console.log(Boolean(obj));  //false
var obj = {}
console.log(Boolean(obj));  //true
var obj2 = { name: 'lisi' }
console.log(Boolean(obj2));  //true
数据类型转换为true的值转换为false的值
Booleantruefalse
String任何非空的字符串""(空字符串)
Number任何非零数字(包括无穷大)0和NaN
Object任何对象null
Undefinedundefined

  • Object类型转String类型
var obj = {
  name:'lisi',
  age: 18,
  // 重写toString方法
  toString:function () {
    return this.name + '-' + this.age
  }
}
console.log(String(obj), obj.toString());  //lisi-18 lisi-18

转换规则:

显示转换与隐式转换规则类似,当要将对象转换为String时,类似隐式转换中的PreferredType为String

1.先调用对象的toString方法

2.判断该方法的返回值是否为基础数据类型(Number,String,Boolean,Undefined,Null)

3.若返回值为基础数据类型,则转换规则按照相应数据类型的转换规则对其进行转换

4.若返回值不为基础数据类型,则在该返回值的基础上继续调用valueOf方法

5.判断valueOf的返回值是否为基础数据类型

6.判断是否为基础数据类型,若是基础数据类型则进行操作3

7.若仍旧不为基础数据类型则报错

  • Object类型转Number类型
var obj = {
  name: 'lisi',
  age: 18,
  // 重写toString方法
  toString: function () {
    return '100'
  },
  // 重写valueOf方法
  valueOf: function () {
    return 10
  }
}
console.log(obj.valueOf()); //10

1. 如果只重写了valueO()或者toString()方法,则调用该方法,并将返回值用Number()转换;

2. 如果两个方法都重写,则调用valueOf(),并将反回值用Number()转换;

3. 如果两个方法都没有重写,则返回NaN。

转换规则:

显示转换与隐式转换规则类似,当要将对象转换为Number时,类似隐式转换中的PreferredType为Number

1.先调用对象的valueOf方法

2.判断该方法的返回值是否为基础数据类型(Number,String,Boolean,Undefined,Null)

3.若返回值为基础数据类型,则转换规则按照相应数据类型的转换规则对其进行转换

4.若返回值不为基础数据类型,则在该返回值的基础上继续调用toString方法

5.判断toString的返回值是否为基础数据类型

6.判断是否为基础数据类型,若是基础数据类型则进行操作3

7.若仍旧不为基础数据类型则报错

检测属性

检测一个属性是否属于某个对象。

in

检测某个属性是否是某对象的自有属性或者继承属性

var obj = {
  name: 'zhangsan',
  age: 20,
  height: 1.78
}
console.log('name' in obj); //true
console.log('age' in obj);  //true
console.log('gender' in obj); //false
//如果用in判断一个属性存在,这个属性不一定是obj的,它可能是obj继承得到的,如:
'toString' in obj;  //  true
因为toString定义在object对象中,而所有对象最终都会在原型链上指向object,所以obj也拥有toString属性。

Object.prototype.hasOwnProperty()

检测给定的属性是否是对象的自有属性,对于继承属性将返回false

var obj = {
  name: 'zhangsan',
  age: 18,
  height: 1.78
}
console.log(obj.hasOwnProperty('name')); //true
console.log(obj.hasOwnProperty('age'));  //true
console.log(obj.hasOwnProperty('toString')); //false,toString为继承属性
console.log(obj.hasOwnProperty('gender')); //false

Object.prototype.propertylsEnumerable()

propertylsEnumerable()是hasOwnProperty()的增强版,除了是自身属性外,还要求是可枚举(可删除的属性)属性,即我们创建的属性。

var obj = {
  name: 'zhangsan',
  age: 18,
  height:1.78
}
console.log(obj.propertyIsEnumerable('name')); //true
console.log(obj.propertyIsEnumerable('age'));  //true
console.log(obj.propertyIsEnumerable('toString')); //false,不可枚举
console.log(obj.propertyIsEnumerable('gender')); //false

Object原型属性及方法(原型方法,实例可以调用的方法)

在Object的构造函数的原型对象中的属性和方法都可以被Object构造函数的实例所继承。

Object原型中的所具有的任何属性和方法也同样存在于其它对象中,任何对象继承自Object。

 总结:每个构造函数都有一个原型对象(prototype),原型对象都包含一个指向构造函数的指针(constructor),实例都包含一个指向原型对象的内部指针(__proto__)。

Object原型中常用的方法

constructor:保存用户创建当前对象的函数,与原型对象对应的构造函数

hasOwnProperty(propertyName):检查给定的属性名是否是对象的自有属性

propertyIsEnumerable(propertyName):检查给定的属性在当前对象实例中是否存在

valueOf():返回对象的字符串,数值,布尔值的表示

toLocaleString():返回对象的字符串表示,该字符串与执行环境的地区对应

toString():返回对象的字符串表示

isPrototypeOf(object):检查传入的对象的原型

a.isPrototypeOf(b) 如果a是b的原型,则返回true。如果b不是对象,或者a不是b的原型,则返回false。

// 使用构造函数创建实例对象
var obj = new Object()

// 调用原型对象中继承的方法
console.log(obj.toString());
console.log(obj.__proto__.toString());

// 构造函数 Object
console.log(Object);  //[Function: Object]
// 原型对象 Object.prototype
console.log(Object.prototype);  // {}
// 原型对象中的constructor属性  原型对象中的constructor属性指向构造函数
console.log(Object.prototype.constructor);  //[Function: Object]
// 实例__proto__ 指向 原型对象
console.log(obj.__proto__ === Object.prototype);  //true

// 创建Date对象
var now = new Date();
console.log(now);
// 使用原型对象中的方法
console.log(now.toString());//Wed Aug 10 2022 19: 58: 37 GMT + 0800(中国标准时间)
console.log(now.toLocaleString());//2022/8/10 下午7:58:37

深入理解对象-定义属性

ECMAScript中有两种属性:数据属性、访问器属性。

数据属性:相当于给当前对象定义了一个公共属性,访问修改直接返回value值;

访问器属性:可以控制访问或者修改这个属性的具体行为。

  • 数据属性特性(默认都是true)

configurable:设置是否可以delete

enumerable:是否可以被for in 循环遍历出来

writable:是否可以修改值

value:设置该属性对应的值

// 字面量和 构造函数创建对象
var person = {
    name: 'zhangsan'
}

// 使用Object.defineProperty来新增定义一个新的属性
Object.defineProperty(person, 'age', {
    // 设置是否可以delete
    configurable: false,
    // 是否可以被for in 循环遍历出来
    enumerable: false,
    // 是否可以修改值
    writable: false,
    // 设置该属性对应的值
    value: 20
})
delete person.age;
console.log(person.age);
for (var key in person) {
    console.log(key);  //20 name
}

person.age = 30
console.log(person.age);//20

//Object.defineProperties()一次性定义多个属性
Object.defineProperties(person, {
    height: {
        configurable: false,
        value: 1.80
    },

    gender: {
        value: '男'
    }
})

console.log(person.gender);  //男

  • 读取属性的特性

Object.getOwnPropertyDescriptor():返回指定对象上一个自有属性对应的属性描述符。

var person = {
    name: 'zhangsan'
}
// 读取对象的属性 Object.getOwnPropertyDescriptor()
console.log(Object.getOwnPropertyDescriptor(person, 'name')); 
// 结果
 //{
//     value: 'zhangsan',
//         writable: true,
//             enumerable: true,
//                 configurable: true
// }
//读取对象的全部属性 getOwnPropertyDescriptors()
console.log(Object.getOwnPropertyDescriptors(person));
// 结果
// {
//     name: {
//         value: 'zhangsan',
//             writable: true,
//                 enumerable: true,
//                     configurable: true
//     }
// }

  • 访问器属性特性

这个属性不包含数据值,包含的是一对get和set方法,在读写访问器属性时,就是通过这两个方法来进行操作处理的。

configurable:设置是否可以delete,默认false。

enumerable:是否可以被for in 循环遍历出来,默认false。

get:在读取属性时调用的函数,默认false。

set:在写入属性时调用的函数,默认undefined。

访问器属性:访问器属性不包含数值,它包含的是一对getter和setter函数;

访问器属性不能像数据属性一样直接定义,它必须使用Object.defineProperty()方法来定义。

// 创建一个对象
var person = {
    // 内部属性
    _birthday: 2000,
    age: 1
}
// 新增一个访问器属性
Object.defineProperty(person, 'birthday', {
    get: function () {
        // return 10
        return this._birthday
    },
    set: function (newValue) {
        if (newValue !== this._birthday) {
            this._birthday = newValue;
            this.age++;
        }
    }
})
// person.birthday get操作 通过点语法获取一个属性的值
person.birthday = 2006;
console.log(person.age);  //2
console.log(person.birthday); //2006

由此可以想到数据的双向绑定:

在一个对象(person)中设置一个私有属性(_birthday:开头下划线代表私有属性),再为这个对象设置访问器属性year(本身还未在对象中定义),当person.birthday进行修改时触发set函数,通过这个函数可以进行数据的操作,比如数据的判断赋值等一系列操作,从而实现数据的双向绑定。这个原理是vue的本质原理。vue是数据驱动框架,当数据发生改变的时候,视图自动更新。

对象序列化

对象序列化是指将对象的状态转换为字符串,也可以反序列化,将字符串还原为对象函数。

// 对象的序列化 和反序列化
// 对象转为JSON字符串
var jsonStr = JSON.stringify(person);
console.log(jsonStr, typeof jsonStr);  //{"name":"zhangsan"} string
// JSON字符串转对象
console.log(JSON.parse(jsonStr));  //{ name: 'zhangsan' }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值