JavaScript对象

7 篇文章 0 订阅
1 篇文章 0 订阅

无序属性的集合,其属性可以包含基本值,对象,或者函数。

key:value键值对的方式呈现。

1. 对象的创建

  • 字面量模式
var obj = {
  name: "zhangsan",
  age: 12,
  sayName: function(){
    console.log("my name is ",this.name);
  }
}
  • 构造函数模式
var obj = new Object();
obj.name = "zhangsan";
obj.age = 12;
obj.sayName = function(){
  console.log("my name is",this.name);
}

2. 对象的访问

  • 属性的访问
// 1. obj.属性名
obj.name;      // 'zhangsan'
// 2. obj['属性名']
obj['name'];     // 'zhangsan'
// 3. obj[变量]
var name = "age";
obj[name];      // 12
  • 方法的访问
obj.sayName;    // 方法的指针
obj.sayName();  // 方法的调用
  • 遍历对象

普通for循环无法变量对象,使用for..in

for(自定义变量名 in 数组/对象){
	执行代码
}
for(var key in obj){
	console.log(obj[key]);  // 'zhangsan' 12 [Function: sayName]
}

3. 新增/删除对象属性

  • 新增属性
obj.newpropertyname = ”value”;
  • 删除属性

只能删除对象的自有属性

delete obj.name;
delete obj[“name”];  // 从obj对象中删除name属性

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

ECMAScript中可用的3种强制类型转换如下:

  • Boolean(value):把给定的值转换成Boolean型。

值的数据类型转化为true的值转换为false的值
Booleantruefalse
String任何非空的字符串""(空字符串)
Number任何非零数字(包括无穷大)0和NaN
Object任何对象null
Undefinedundefined
  • String(value):把给定的值转换成字符串。

  • Number(value):把给定的值转换成字符串。

  • Object类型转String类型

转换规则:

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

1.先调用对象的toString方法

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

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

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

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

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

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

  • Object类型转Number类型

转换规则:

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

1.先调用对象的valueOf方法

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

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

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

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

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

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

5.检测属性

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

  • in

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

var obj = {
  name: 'zhangsan',
  age: 18,
  school: 'xx大学'
}
//in运算符的左侧为属性名称,右侧为对象
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,
  school: 'xx大学'
}
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()的增强版,除了是自身属性外,还要求是可枚举属性

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

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

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

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

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

Object原型中的属性及方法:

  • constructor

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

  • hasOwnProperty(propertyName)

        检查给定的属性名是否是对象的自有属性

  • propertylsEnumerable(propertyName)

        检查给定的属性在当前对象实例中是否存在

  • valueOf()

        返回对象的字符串,数值,布尔值的表示

  • toLocaleString()

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

  • toString()

        返回对象的字符串表示

  • isPrototypeOf(object)

        检查传入的对象的原型

// 使用构造函数创建实例对象
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());//'Fri Oct 08 2021 17:24:47 GMT+0800 (GMT+08:00)' (中国标准时间)
console.log(now.toLocaleString());  // '2021/10/8 下午5:24:47'

7.深入理解对象-定义属性

ECMAScript中有两种属性:数据属性、访问器属性。这两种属性用于设置属性的高级属性,例如该属性是否可以配置,是否可以读写,是否可以遍历,并且可以通过setter,getter来监听数据的改变。

  • 数据属性的特征

        [[Configurable]] :表示是否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性(属性直接定义在对象中,默认为true)。 当为false时,不能重新定义不能使用delete删除。

        [[Enumerable]] :表示能否通过for-in循环返回属性。(属性直接定义在对象中,默认为true)

        [[Writable]] :表示能否修改属性的值。(属性直接定义在对象中,默认为true)

        [[Value]] :包含这个属性的数据值

Object.defineProperty(属性所在的对象,属性的名字,一个描述符对象) 

除了直接添加属性的方式,还可以使用Object.defineProperty定义新属性或修改原有的属性。

Object.defineProperty(obj,'name',{
   configurable:true,
   enumerable:true,
   writable:true,
   value:'terry'
})
console.log(obj.name); 
Object.defineProperty(obj,"name",{enumerable:false})
obj.propertyIsEnumerable("name");//false

Object.defineProperties(obj, props)

var obj = new Object();
Object.defineProperties(obj, {
    name: {
        value: 'zhangsan',
        configurable: false,
        writable: true,
        enumerable: true
    },
    age: {
        value: 18,
        configurable: true
    }
})
console.log(obj.name, obj.age) // zhangsan, 18
  • 读取属性的特征

Object.getOwnPropertyDescriptor(obj, prop) 该方法返回指定对象上一个自有属性对应的属性描述符。

var person = {
    name: '张三',
    age: 18
}

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

 Object.getOwnPropertyDescriptors(obj) 所指定对象的所有自身属性的描述符,如果没有任何自身属性,则返回空对象。

var person = {
    name: '张三',
    age: 18
}
var desc = Object.getOwnPropertyDescriptors(person);
console.log(desc) 
//{
//    configurable: true,
//    enumerable: true,
//    value: '张三',
//    writable: true
//}
  • 访问器属性特征

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

访问器属性包含的四个特性:

[[Configurable]]:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或能否把属性修改为访问器属性, 默认为false。

[[Enumerable]]:表示能否通过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'));

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

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

8.对象序列化

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

RegExp,Error对象,undefined值不能序列化和反序列化。

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

JSON.parse(jsonStr) 反序列化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值