JavaScript(4)对象

目录

对象

对象的创建

字面量模式

构造函数模式

对象的访问

属性访问

方法的访问

遍历对象中的属性

新增删除对象中的属性

Object显示类型转换(强制类型转换)

Object类型转换到Boolean类型

Object类型转String类型

方法重写

Object类型转Number类型

方法重写

检测属性

in

Object.prototype.hasOwnProperty()

Object.prototype.propertyIsEnumerable()

深入理解对象-定义属性

数据属性特性

读取属性的特性

访问器属性特性

序列化和反序列化


对象

什么是对象?在我们的现实生活当中万物皆是对象,对象就是一个具体的事物,看得见摸得着的实物。例如,一本书、一辆汽车、一个人都是对象。而一个人的身高、体重、性别都是这个人对象的属性,人的走路和跑步、说话就是这个人对象的方法。

对象的创建

字面量模式

通过字面量模式的创建的对象的属性需要逗号 ',' 隔开(下文中的所有obj全部使用的是通过字面量模式创建的该变量)

var obj = {
    name:'zhangsan',
    age:20,
    sayName:function(){
        console.log(this.name);
    }
}

构造函数模式

使用Object或者使用自定义构造函数来初始化对象(例如Student)

通过 .语法来向对象中添加我们需要的属性

var obj = new Object();
obj.name = 'zhangsan';
obj.age = 20;
obj.sayName = function(){
    console.log(this.name);
}

//也可以这样创建对象
var obj = {};
obj.name = 'zhangsan';
obj.age = 20;
obj.sayName = function(){
    console.log(this.name);
}

对象的访问

属性访问

通过 点语法 和 中括号 的方式来进行对象的属性访问

点后面直接跟的是对象的属性,如果属性存在可以访问到,如果属性不存在,得到undefined。 中括号的方法也同理。

console.log(obj.name);      //'zhangsan'
console.log(obj['name']);     //'zhangsan'

方法的访问

方法的访问主要是为了执行该对象中的方法,需要按照函数调用的方式去使用

//以下执行结果不一样
obj.sayName;//无执行结果
obj.sayName();//方法的使用

遍历对象中的属性

普通版的for循环可以遍历数组,但无法遍历对象

增强版的for循环:

for..in用于遍历数组或者对象的属性

obj对象:依次从obj中获取到属性名 “自定义变量名key”用来指定是数组的元素索引,也可以是对象的属性

for(var key in obj){
	var value = obj[key];
    console.log(value);
}
//zhangsan
//20
//[Function: sayName]

新增删除对象中的属性

只能删除对象中原有的自有属性

delete obj.age;
delete obj['name'];
delete obj.sayName     //从obj对象中删除sayName属性

console.log(obj) //{}

新增对象的属性

obj.gender = 'female'
console.log(obj) //{ name:'zhangsan', age:20, [function:sayName], gender:'female'}

Object显示类型转换(强制类型转换)

Object类型转换到Boolean类型

除了空引用(null)会转换为false,其他都被转换为true

// 除了空引用(null)会转换为false,其他都被转换为true
// 使用Boolean包装器进行转换
console.log(Boolean(obj)); // true

Object类型转String类型

转换规则:

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

1.先调用对象的toString方法

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

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

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

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

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

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

console.log(obj.toString(), typeof obj.toString()); //[object Object] string
console.log(String(obj), typeof String(obj)); //[object Object] string

方法重写

        1.如果只重写了valueOf()方法,则调用toString()方法。
        2.如果只重写了toString()方法,则调用toString()方法。
        3.如果两个方法都重写了,则调用valueOf(),并将返回值用String()转换。

var obj = {
  name:'zhangsan',
  age:20,
  sayName:function(){
    console.log(this.name);
  },
  /*
		1.如果只重写了valueOf()方法,则调用toString()方法。
        2.如果只重写了toString()方法,则调用toString()方法。
		3.如果两个方法都重写了,则调用toString()。
        4.如果上述中的toString()方法都无法转换成基础数据类型,那就调用valueOf()方法,若仍旧不为基础数据类型则报错
	*/ 
  toString:function(){
    return "100";
  },
  valueOf:function(){
    return 10;
  }
};
console.log(Number(obj)); //100

Object类型转Number类型

转换规则:

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

1.先调用对象的valueOf方法

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

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

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

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

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

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

console.log(Number(obj)); //NaN

方法重写

        1.如果只重写了valueOf()或者toString()方法,则调用该方法,并将返回值用Number()转换。
        2.如果两个方法都重写了,则调用valueOf(),并将返回值用Number()转换。
        3.如果两个方法都没有重写,则返回NaN

var obj = {
  name:'zhangsan',
  age:20,
  sayName:function(){
    console.log(this.name);
  },
  /*
		1.如果只重写了valueOf()或者toString()方法,则调用该方法,并将返回值用Number()转换。
		2.如果两个方法都重写了,则调用valueOf(),并将返回值用Number()转换。
		3.如果两个方法都没有重写,则返回NaN
	*/ 
  toString:function(){
    return "100";
  },
  valueOf:function(){
    return 10;
  }
}
console.log(Number(obj)); //10

检测属性

检测一个属性是否属于某个对象。常用的方式主要有3种: in、Object.prototype.hasOwnProperty()、Object.prototype.propertyIsEnumerable()

in

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

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

Object.prototype.hasOwnProperty()

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

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.propertyIsEnumerable()

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

console.log(obj.propertyIsEnumerable('name')); //true
console.log(obj.propertyIsEnumerable('age'));  //true
console.log(obj.propertyIsEnumerable('toString')); //false,不可枚举
console.log(obj.propertyIsEnumerable('gender')); //false

深入理解对象-定义属性

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

数据属性特性

  configurable:true, //表示是否通过delete删除属性从而重新定义属性,能否修改属性的特性,默认为true
  enumerable:true,//表示能否通过for-in循环返回属性 默认为true
  writable:true, //表示能否修改属性的值 默认为true
  value:'zhangsan' //属性的值

Object.defineProperty():

定义新属性或修改原有的属性。

//(属性所在的对象,属性的名字,一个描述符对象)
Object.defineProperty(obj,'name',{
  configurable:true, //表示是否通过delete删除属性从而重新定义属性,能否修改属性的特性,默认为true
  enumerable:true,//表示能否通过for-in循环返回属性 默认为true
  writable:true, //表示能否修改属性的值 默认为true
  value:'zhangsan'
})
console.log(obj.name); 
Object.defineProperty(obj,"name",{enumerable:false})
console.log(obj.propertyIsEnumerable("name"));//false

Object.defineProperties():

定义一个或者多个新属性或修改原有的属性。

//defineProperties(目标对象,该对象的一个或者多个键值)
Object.defineProperties(obj, {
    name: {
        value: 'zhangsan',
        configurable: false,// 不可以通过delete删除属性
        writable: true,
        enumerable: true
    },
    age: {
        value: 18,
        configurable: true
    }
})
console.log(delete obj.name); //false
console.log(obj.name, obj.age) // zhangsan 18

读取属性的特性

Object.getOwnPropertyDescriptor():

返回指定对象上一个自有属性对应的属性描述符

var desc = Object.getOwnPropertyDescriptor(obj, 'name'); 
console.log(desc)  结果如下
// {
//     configurable: true,
//     enumerable: true,
//     writable: true,
//     value: "zhangsan"
// }

Object. getOwnPropertyDescriptors():

返回指定对象所有自有属性对应的属性描述符

var desc = Object.getOwnPropertyDescriptors(obj);
console.log(desc) 

// {
//   name: {
//     value: 'zhangsan',
//     writable: true,
//     enumerable: true,
//     configurable: true
//   },
//   age: { value: 20, writable: true, enumerable: true, configurable: true },
//   sayName: {
//     value: [Function: sayName],
//     writable: true,
//     enumerable: true,
//     configurable: true
//   }
// }

访问器属性特性

  configurable:true, //表示是否通过delete删除属性从而重新定义属性,能否修改属性的特性,默认为false
  enumerable:true,//表示能否通过for-in循环返回属性 默认为false

get:在读取属性时调用的函数,默认值为undefined

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

访问器属性不能直接定义,要通过Object.defineProperty()这个方法来定义。

/** 
 * 访问器属性:访问器属性不包含数值,它包含的是一对getter和setter函数;
 * 访问器属性不能像数据属性一样直接定义,它必须使用Object.defineProperty()方法来定义
 */
 var book = {
  _year: 2020, //下划线表示是内部属性,只能通过对象的方法来读写
  editor: 1
};
Object.defineProperty(book, 'year', {
  get: function () {
    return this._year;
  },
  // 若只指定get方法,不指定set方法,那就默认该属性是只读的
  set: function (newYear) {
    if (newYear !== this._year) {
      this._year = newYear
      this.editor ++
    }
  }
});
// 测试访问属性中的get,set方法
console.log('未修改的year:' + book.year);
book.year = 2021;
console.log('修改后的year:' + book.year);
console.log('修改year后的editor:' + book.editor);
// 访问器属性可以通过Object.getOwnPropertyDescriptor()查询
console.log(Object.getOwnPropertyDescriptor(book, '_year'));

序列化和反序列化

JSON.stringify(obj) 将对象序列化为JSON字符串,只能序列化对象可枚举的自有属性

JSON.parse(jsonStr) 反序列化

var json = JSON.stringify(obj);
console.log(json);//string类型的字符串
// 将JSON字符串转换为对象
var obj = JSON.parse(json);
console.log(obj);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值