js数据类型--object

系列文章

1 、从数据类型讲原型原型链html

内容回顾

在JavaScript中,数据类型能够分为原始类型以及引用类型es6

其中原始类型包括string,number, boolean, null, undefined, symbol(ES6新增,表示独一无二的值),这6种数据类型是按照值进行分配的,是存放在(stack)内存中的简单数据段,能够直接访问,数据大小肯定,内存空间大小能够分配。编程

引用类型包括function,object,array等能够可使用new建立的数据,又叫对象类型,他们是存放在(heap)内存中的数据,如var a = {},变量a实际保存的是一个指针,这个指针指向对内存中的数据 {}segmentfault

对象类型包含但不限于object、function、array、string、boolean、number、date、regexp。数组

这一篇文章则主要讲object类型的功能及用法。数据结构

1、开篇

在js中,function类型的数据叫函数,又叫方法,array类型的数据叫数组,而object类型的数据就叫对象,须要根据实际状况来区分一些文章中的对象与对象类型。函数

什么是对象?动画

对象就是封装一个事物的属性和功能的程序结构,是内存中保存多个属性和方法的一块存储空间。this

什么是面向对象编程?spa

面向对象编程(OOP)是一种编程思想,是一种对现实世界理解和抽象的方法,是计算机编程技术发展到必定阶段后的产物。它的特征是封装、继承、多态,优势是易维护、易扩展、质量高、效率高。通俗的讲就是以对象为基础来进行软件开发的思想,举个例子,好比咱们作一个雨滴落地的动画,那么能够用面向对象的方法把雨滴当作一个对象,这个对象中包含颜色、形状、大小、速度等属性,同时还包括了开始下落、下落过程、落地后等方法 。

2、建立对象

一、直接量(字面量)建立

由于这种建立方法很直接,因此叫直接量,又叫字面量

var obj = {a:1}

二、构造函数建立

这一方法建立对象又叫工厂函数建立对象,顾名思义就是批量生产,使用这个方法咱们须要用到关键字new。运行环境内置了一个对象的构造函数—Object,咱们直接使用就能够了

var  obj = new Object({a:1});

上面的例子中,咱们在Object中加了一个参数,这个参数是初始化的值(将参数赋值给新对象,不是克隆),这个参数的格式须要符合对象的格式要求,若是你传入了一个别的类型的参数,那么建立的就不是object类型的对象了(数据类型仍是对象,但不是object)

var a = new Object('a'); // String {"a"}
var b = new Object('{a:1}'); // String {"{a:1}"}
var c = new Object(1); // Number {1}

另外,若是没有参数须要传入,则Object后面的()能够省略,即

var a = new Object; //{}

除了环境自带的构造函数,咱们还能够根据实际需求自定义构造函数

function Student(name,age){
    this.name = name
    this.age = age
}
var xm = new Student(‘xiaoM’,12); // Student {name: "xiaoM", age: 12}
var xh = new Student(‘xiaoH’,14); // Student {name: "xiaoH", age: 14}

三、Object.create建立对象

咱们知道,Object是一个构造函数,而js中函数也是对象类型的数据,因此函数也是有属性的,而create就是其中的一个方法,该方法的做用是根据现有的对象新建立一个子对象。

var son=Object.create(父对象);

这句话作了2件事:

1. 建立空对象son
2. 设置son的__proto__指向父对象

上面的解释实际上是有一点瑕疵的,由于咱们不但能够根据现有的对象来建立子对象,还能够根据null来建立子对象,我这么说是想强调下null不是一个对象,虽然Object.prototype继承自null,但null也不是一个对象,你可能会说:

typeof null === "object" // true
Object.prototype.toString(null) === "[object Object]" // true

但它确实不是一个对象,这是js的历史遗留问题,详细能够看这里 typeof null的前世此生

继续回到咱们的文章上来,若是咱们使用了null做为父对象来建立一个子对象,那么

子对象.__proto__ === null //true

和Object.prototype一个级别的!!!不过不一样的是,Object.prototype是运行环境封装的,里面天生有一些属性及方法,而用null建立的子对象就像一个新生儿同样,里面干干净净的,什么都没有。

使用null建立子对象的缺点就是咱们再也不可以使用Object.prototype自带的一些属性及API,若是须要的话,你就得本身去实现了,好处就是这个子对象是一个干干净净的对象,里面的一些属性及方法能够按照本身的想法来,不用担忧与原型链上属性重名,形成变量污染,多用于存储数据。

四、ES6 的 class建立对象

class关键字是ES6引入的概念,用于定义类(对象),用法以下:

//定义类
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}

能够看到里面有一个constructor方法,这就是构造方法,而this关键字则表明实例对象Point。

Point类除了构造方法,还定义了一个toString方法。注意,定义“类”的方法的时候,前面不须要加上function这个关键字,直接把函数定义放进去了就能够了。另外,方法之间不须要逗号分隔,加了会报错。

ES6 的类,彻底能够看做构造函数的另外一种写法。

class Point {
  // ...
}

typeof Point // "function"
Point === Point.prototype.constructor // true

上面代码代表,类的数据类型就是函数,类自己就指向构造函数。使用的时候,也是直接对类使用new命令,跟构造函数的用法彻底一致。

var point = new Point(2,3);
point.toString() // "(2,3)"

这里执行new Point(2,3)能够看做是执行了类Point里的constructor方法为x,y赋值,同时把toString函数挂到Point.prototype上去

构造函数的prototype属性,在 ES6 的“类”上面继续存在。事实上,类的全部方法都定义在类的prototype属性上面。

更多class的使用说明及其余es6的特性看一看阮一峰老师的ECMAScript 6 入门,讲的很详细,上面关于class的讲解也都摘抄自阮一峰老师的这本书里。

3、对象的遍历

遍历就是依次处理该数据结构的全部成员,JavaScript中的遍历是针对表示“集合”的数据结构,主要是数组(Array)和对象(Object),ES6 又添加了Map和Set。其中对象的遍历主要是使用for…in结构,用法以下:

var a = {a:1,b:2}
for(var k in a){
    console.log(k)
}
//a b

for…in 的使用中,咱们须要当心的是,他不但能够遍历本身的私有属性,还会遍历其原型链上的公有属性。

私有属性:对象自己所具备的属性
公有属性:包括私有属性在内的其原型链上的可访问到的属性

var a = {a:1,b:2}
a.__proto__ = {c:4}
for(var k in a){
    console.log(k)
}
//a b c

咱们能够经过obj.hasOwnProperty来判断一个属性是否是对象的自有属性

for(var k in a){
    if( a.hasOwnProperty( k ) ){
        console.log(k)
    }
}
//a b

以上,咱们把全部能够遍历到的属性叫作可枚举属性,那么什么是可枚举属性不可枚举属性呢?

可枚举属性是指那些内部 “可枚举” 标志(enumerable)设置为 true 的属性,对于经过直接的赋值和属性初始化的属性,该标识值默认为即为 true,对于经过 Object.definePropertyObject.create 等定义的属性,该标识值默认为 false。可枚举的属性能够经过 for...in 循环进行遍历(除非该属性名是一个 Symbol)。相对的,不可枚举属性就是用 for...in 遍历不到的属性,js中内置属性是遍历不到的。

4、Object/Object.prototype经常使用API介绍

咱们知道不管是object、function、array仍是string、boolean、number、date,他们都是对象类型的数据,咱们在可使用console.dir()来查看一个数据的结构。这样咱们就能够很全面的看到一个对象上有哪些属性了。

一、Object构造函数的方法

Object是object的构造函数,咱们使用console.dir(Object),能够看到:

Object

Object.assign()
经过复制一个或多个对象来建立一个新的对象。

Object.create()
使用指定的原型对象和属性建立一个新对象。

Object.defineProperty()
给对象添加一个属性并指定该属性的配置。

Object.defineProperties()
给对象添加多个属性并分别指定它们的配置。

Object.entries()
返回给定对象自身可枚举属性的[key, value]数组。

Object.freeze()
冻结对象:其余代码不能删除或更改任何属性。

Object.getOwnPropertyDescriptor()
返回对象指定的属性配置。

Object.getOwnPropertyNames()
返回一个数组,它包含了指定对象全部的可枚举或不可枚举的属性名。

Object.getOwnPropertySymbols()
返回一个数组,它包含了指定对象自身全部的符号属性。

Object.getPrototypeOf()
返回指定对象的原型对象。

Object.is()
比较两个值是否相同。全部 NaN 值都相等(这与==和===不一样)。

Object.isExtensible()
判断对象是否可扩展。

Object.isFrozen()
判断对象是否已经冻结。

Object.isSealed()
判断对象是否已经密封。

Object.keys()
返回一个包含全部给定对象自身可枚举属性名称的数组。

Object.preventExtensions()
防止对象的任何扩展。

Object.seal()
防止其余代码删除对象的属性。

Object.setPrototypeOf()
设置对象的原型(即内部[[Prototype]]属性)。

Object.values()
返回给定对象自身可枚举值的数组。

二、Object 实例和Object 原型对象的方法

Object.prototype自己是一个对象,因此咱们使用console.log(Object.prototype),就能够看到他的结构:

Object.prototype

Object.prototype.hasOwnProperty()
返回一个布尔值 ,表示某个对象是否含有指定的属性,并且此属性非原型链继承的。

Object.prototype.isPrototypeOf()
返回一个布尔值,表示指定的对象是否在本对象的原型链中。

Object.prototype.propertyIsEnumerable()
判断指定属性是否可枚举

Object.prototype.toLocaleString()
直接调用 toString()方法。

Object.prototype.toString()
返回对象的字符串表示。

Object.prototype.valueOf()
返回指定对象的原始值。

因为 Object 以及 Object.prototype 的属性太多,这里就不详细阐述了,感兴趣的小伙伴能够到 MDN 观看,强烈建议把Object、Object.prototype的属性都过一遍。

相关文章
相关标签/搜索