《JS原理、方法与实践》- object类型对象

简介: 《JS原理、方法与实践》- object类型对象

ES中一共由两种对象,function和object。object类型对象时ES的基础,它主要通过属性使用。

#### 创建object类型对象的三种方式

ES中object类型的对象大致由三种创建方式:直接使用花括号创建、使用function创建、使用Object.create方法创建。

###### 直接使用花括号创建

代码示例:

```

var obj = {

v: 6,

innerObj: {

 v: 7,

},

logV: function() {

 console.log(this.v);

}

};

console.log(obj.v); // 6

console.log(obj.innerObj.v); // 7

obj.logV(); // 6

```

![](https://upload-images.jianshu.io/upload_images/2789632-637e7ff57a1b3105.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

###### 使用function创建

对于一个function类型的对象,使用new便是对象,不使用便是函数。一般是对象的话,首字母大写,方法首字母小写。

举例:

```

function F(){

 this.v = 1;

}

var obj = new F();

console.log(obj.v);

```

![](https://upload-images.jianshu.io/upload_images/2789632-55975fb82a573465.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

###### 使用Object.create方法创建

Object是ES中内置的一个function类型的对象,create是Object对象的一个属性方法,其作用是根据传入的参数创建object类型的对象。create方法的调用语法如下:

Object.create(prototype,  [propertiesObject]);

第一个参数prototype是创建的对象所对应的prototype,相当于使用function创建时中的prototype属性对象,创建出来的object对象实例可以直接调用。

第二个参数propertiesObject为属性描述对象,是可选参数,用于描述所创建对象的自身属性。属性描述对象是object类型对象,它里面的属性名会成为所创建对象的属性名,属性值为属性的描述对象。

Object.getOwnPropertyNames(obj):获取obj自己所拥有的属性。

代码示例:

```

var obj = Object.create(

{

 type: 'by create'

},

{

 color:{

  value: 'red',

  enumerable: true,

 },

 size:{

  value: '37',

  enumerable: true,

 }

}

);

console.log(obj.type); // by create

console.log(obj.color); // red

console.log(obj.size); // 37

console.log(Object.getOwnPropertyNames(obj)); // ['color', 'size']

```

![](https://upload-images.jianshu.io/upload_images/2789632-69df142e74655e83.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

###### Object的prototype属性对象里面都有什么

Object的prototype属性对象在ES5.1和ES2015中都规定了constructor、toString()、toLocaleString()、valueOf()、哈sOwn Property(V)、isPrototypeOf(V)和propertyIsEnumerable(V)7个属性。

* toString: 可以将对象转换为字符串,不同类型的对象可能会重写自己的toString方法。

* toLocaleString: 会使用本地化格式来生成字符串,对于时间日期类型和数字类型的用处较大。

* valueOf: 会返回原始值。例如Date的valueOf就是相应的数字。

* hasOwnProperty: 判定是否包含指定属性。

* isPrototypeOf: 判断某个对象是否是另一个对象所对应的prototype对象。

* propertyIsEnumerable: 判断某个属性是否可以枚举。

标准中所规定的Object的prototype属性对象中的7个属性,但是不同的浏览器还会有自己的扩展。

#### 对象的属性

对象是通过其属性发挥作用的,因此对象的属性是对象的核心。

###### 三种属性类型

命名数据属性(named data properties)、命名访问器属性(named accessor properties)和内部属性(internal properties)。

###### 命名数据属性

命名数据属性是我们平时使用最多的属性,由属性名和属性值组成。

代码示例:

```

var obj = {

v: 6,

innerObj: {

 v: 7,

},

logV: function() {

 console.log(this.v);

}

};

console.log(obj.v); // 6

console.log(obj.innerObj.v); // 7

obj.logV(); // 6

```

![](https://upload-images.jianshu.io/upload_images/2789632-637e7ff57a1b3105.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

###### 命名访问器属性(getter/setter)

getter和setter是对应的方法,setter方法用于给属性赋值,而getter方法用于获取属性的值。如果只有getter、setter其中之一,就只能进行单一操作,例如只有getter方法的属性就是只读属性,只有setter方法的属性就是只可以写入的属性。

代码示例:

```

function log(msg){

console.log(msg);

};

var car = {

_color: 'red',

_weight: 0,

_age: 0,

 

// color 可读,可写

get color(){

 return this._color;

},

 

set color(col){

       log('color changed');

 this._color = col;

},

// weight只读不写

get weight(){

 return this._weight;

},

// age 只写不读

set age(age){

 this._age = age;

},

};

car.color='blue';

log(car.color); // 'blue'

log(car.weight); // 0

car.age=10;

log(car.age); // undefined

```

![测试结果](https://upload-images.jianshu.io/upload_images/2789632-64c2ef87792e1517.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

###### 内部属性

内部属性是对象的一种特殊的属性。它没有自己的名字,当然也就不可以像前两种属性那样直接访问了。正是因为内部属性没有名字所以前面两种属性才叫命名属性。内部属性使用两对方括号表示。例如, [[Extensible]]表示Extensible内部属性。

内部属性的作用是用来控制对象本身的行为。所有对象共有的内部属性共12个:[[ptototype]]、[[Class]]、[[Extensible]]、[[Get]]、[[GetOwnProperty]]、[[GetProperty]]、[[Put]]、[[CanPut]]、[[HasProperty]]、[[Delete]]、[[DefaultValue]]、[[DefineOwnProperty]]除了这12个之外,不同的对象可能还会有自己的内部属性。

下面简单介绍一种内部属性:[[Prototype]]

它就是使用function创建对象时function中的prototype属性。

注意使用Object.getPrototypeOf()方法来获取prototype.

代码示例:

```

function Car(){}

Car.prototype = {color: 'red'};

var car = new Car();

console.log(typeof car.prototype); // undefined

console.log(Object.getPrototypeOf(car)); // 'red'

```

![](https://upload-images.jianshu.io/upload_images/2789632-11b887e258155db5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

#### 5种创建属性的方式

###### 1. 使用花括号创建

代码示例:

```

var obj = {

v: 1, // 直接量属性

 

// function 对象属性

getV: function() {

 return this.v;

},

// 访问器属性(name)

_name: 'object',

get name() {

 return this._name;

},

set name(name){

 this._name = name;

}

};

console.log(obj.v); // 1

console.log(obj.getV()); // 1

console.log(obj.name); // 'object'

obj.name = 'objChanged';

console.log(obj.name); // 'objChanged'

```

![](https://upload-images.jianshu.io/upload_images/2789632-b17226ecfedeffff.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

###### 2. 使用点操作符创建

当使用点操作符给一个对象赋值时,如果对象存在此属性则会修改属性的值,否则会添加相应的属性并赋予相应的值。

代码示例:

```

var person = {name: 'zzh'};

person.name = 'zh';

person.age = 18;

console.log(person); // { name: 'zh', age: 18 }

```

![](https://upload-images.jianshu.io/upload_images/2789632-9647dbd0b6660cb2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

###### 3. Object的create方法

第一个参数为创建对象的[[Prototype]]属性,第二个参数为属性描述对象。

代码示例:

```

var obj = Object.create(

{

 type: 'by create'

},

{

 color:{

  value: 'red',

  enumerable: true,

 },

 size:{

  value: '37',

  enumerable: true,

 }

}

);

console.log(obj.type); // by create

console.log(obj.color); // red

console.log(obj.size); // 37

console.log(Object.getOwnPropertyNames(obj)); // ['color', 'size']

```

![](https://upload-images.jianshu.io/upload_images/2789632-69df142e74655e83.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

###### 4.Object的defineProperty、defineProperties方法

使用Object的defineProperty和defineproperties方法给对象添加属性。defineProperty方法可添加单个属性,defineProperties方法可以添加多个属性。

代码示例:

```

var person = {};

Object.defineProperty(person, 'name', {

enumerable: true,

value: 'zzh'

});

console.log(Object.getOwnPropertyNames(person)); // ['name']

console.log(person.name); // zzh

Object.defineProperties(person, {

name: {

enumerable: true,

value: 'zzh'

},

age: {

enumerable: true,

value: 18

}

});

console.log(Object.getOwnPropertyNames(person)); // ['name', 'age']

console.log(person.name); // zzh

console.log(person.age); // 18

```

![](https://upload-images.jianshu.io/upload_images/2789632-0d8ad4eb12f36385.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

###### 5. 通过prototype属性创建

使用function创建的object实例对象可以使用function对象的prototype属性对象中的属性。

代码示例:

```

function Person(){}

var person = new Person();

Person.prototype.name = 'zzh';

console.log(person.name); // zzh

```

![](https://upload-images.jianshu.io/upload_images/2789632-550ce3c78a538542.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

#### 属性的描述

属性的描述也可以称为属性的特征,类似于对象的内部属性,其主要作用就是描述属性自己的一些特征。

###### 命名数据属性的4个特征

* [[Value]]: 表示属性的值

*  [[Writable]]: 表示属性值是否可以修改

*   [[Enumerable]]: 表示属性是否可枚举, 若为false则不会被for-in循环遍历到。

*  [[Configurable]]:表示属性是否可以被删除和属性的特性(除[[value]]外)是否可修改。

代码示例:

```

var person = {};

Object.defineProperty(person, 'name', {

enumerable: true,

value: 'zzh',

writable: false, // 不可修改

configurable: true

});

console.log(Object.getOwnPropertyNames(person)); // ['name']

console.log(person.name); // zzh

person.name = 'zh'; // not work

console.log(person.name); // zzh

```

![](https://upload-images.jianshu.io/upload_images/2789632-283a83c68909ac68.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

###### 命名访问器属性的4个特征

* [[Get]]:getter方法

* [[Set]]: setter方法

* [[Enumerable]]:表示属性是否可枚举, 若为false则不会被for-in循环遍历到。

* [[Configurable]]:表示属性是否可以被删除和属性的特性(除[[value]]外)是否可修改。

代码示例:

```

function log(msg){

console.log(msg);

}

var person = {_name: '007'};

Object.defineProperty(person, 'name', {

get: function(){

 log('getting name');

 return this._name;

},

 

set: function(newName){

 log('name is changed to ' + newName);

 this._name = newName;

}

});

log(Object.getOwnPropertyDescriptor(person, 'name'));  

//{ get: [Function: get],set: [Function: set], enumerable: false,configurable: false }

console.log(person.name); // 007

person.name = 'zzh';  

console.log(person.name); // zzh

```

![测试结果](https://upload-images.jianshu.io/upload_images/2789632-b528a5d61c997dcd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

目录
相关文章
|
1月前
|
JavaScript 前端开发
如何在 JavaScript 中使用 __proto__ 实现对象的继承?
使用`__proto__`实现对象继承时需要注意原型链的完整性和属性方法的正确继承,避免出现意外的行为和错误。同时,在现代JavaScript中,也可以使用`class`和`extends`关键字来实现更简洁和直观的继承语法,但理解基于`__proto__`的继承方式对于深入理解JavaScript的面向对象编程和原型链机制仍然具有重要意义。
|
1月前
|
Web App开发 JavaScript 前端开发
如何确保 Math 对象的方法在不同的 JavaScript 环境中具有一致的精度?
【10月更文挑战第29天】通过遵循标准和最佳实践、采用固定精度计算、进行全面的测试与验证、避免隐式类型转换以及持续关注和更新等方法,可以在很大程度上确保Math对象的方法在不同的JavaScript环境中具有一致的精度,从而提高代码的可靠性和可移植性。
|
1月前
|
JavaScript 前端开发 开发者
如何在 JavaScript 中处理不同类型的错误?
【10月更文挑战第29天】通过对不同类型错误的准确识别和恰当处理,可以提高JavaScript程序的可靠性和稳定性,减少错误对程序运行的影响。
|
1月前
|
JSON 前端开发 JavaScript
JavaScript中对象的数据拷贝
本文介绍了JavaScript中对象数据拷贝的问题及解决方案。作者首先解释了对象赋值时地址共享导致的值同步变化现象,随后提供了五种解决方法:手动复制、`Object.assign`、扩展运算符、`JSON.stringify`与`JSON.parse`组合以及自定义深拷贝函数。每种方法都有其适用场景和局限性,文章最后鼓励读者关注作者以获取更多前端知识分享。
19 1
JavaScript中对象的数据拷贝
|
1月前
|
开发框架 JavaScript 前端开发
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势。通过明确的类型定义,TypeScript 能够在编码阶段发现潜在错误,提高代码质量;支持组件的清晰定义与复用,增强代码的可维护性;与 React、Vue 等框架结合,提供更佳的开发体验;适用于大型项目,优化代码结构和性能。随着 Web 技术的发展,TypeScript 的应用前景广阔,将继续引领 Web 开发的新趋势。
38 2
|
1月前
|
JSON 前端开发 JavaScript
聊聊 Go 语言中的 JSON 序列化与 js 前端交互类型失真问题
在Web开发中,后端与前端的数据交换常使用JSON格式,但JavaScript的数字类型仅能安全处理-2^53到2^53间的整数,超出此范围会导致精度丢失。本文通过Go语言的`encoding/json`包,介绍如何通过将大整数以字符串形式序列化和反序列化,有效解决这一问题,确保前后端数据交换的准确性。
43 4
|
1月前
|
设计模式 JavaScript 前端开发
js中new和object.creat区别
【10月更文挑战第29天】`new` 关键字和 `Object.create()` 方法在创建对象的方式、原型链继承、属性初始化以及适用场景等方面都存在差异。在实际开发中,需要根据具体的需求和设计模式来选择合适的方法来创建对象。
|
1月前
|
JavaScript 前端开发 Java
除了 JavaScript,还有哪些编程语言支持 Set 类型
【10月更文挑战第30天】这些编程语言中的 `Set` 类型虽然在语法和具体实现细节上有所不同,但都提供了类似的集合操作功能,方便开发者在不同的编程场景中处理集合相关的数据和逻辑。
|
1月前
|
JavaScript 前端开发 图形学
JavaScript 中 Math 对象常用方法
【10月更文挑战第29天】JavaScript中的Math对象提供了丰富多样的数学方法,涵盖了基本数学运算、幂运算、开方、随机数生成、极值获取以及三角函数等多个方面,为各种数学相关的计算和处理提供了强大的支持,是JavaScript编程中不可或缺的一部分。
|
1月前
|
存储 JavaScript 前端开发
js的基础类型和引用类型
【10月更文挑战第29天】理解 JavaScript 中的基础类型和引用类型的区别对于正确地编写代码和理解程序的行为非常重要。在实际开发中,需要根据具体的需求合理地选择和使用不同的数据类型,以避免出现一些意想不到的错误和问题。同时,在处理引用类型数据时,要特别注意对象的引用关系,避免因共享引用而导致的数据不一致等问题。