【JS标准库-1】Object对象

240 阅读4分钟

概述

JS中有很多标准库对象,本文将介绍Object对象的原生方法。

Object对象原生方法分为两种:定义在本身上的方法(又称静态方法)和定义在原型上的方法(又称实例方法)

Object()

Object本身是一个函数,可以当作工具将所有值都转化为对象。这个方法经常用来保证某样东西一定是对象。

如果参数为空,或者为undefined或null,那么就返回一个对象

let a =Object()
let b =Object(undefined)
let c =Object(null)
a //{}
b //{}
c //{}

instanceof

我们可以用instanceof运算符验证,

某个值的原型链中有没有关联到构造函数的prototype。继而判断这个实例是否由对应的构造函数构成

例如我们经常用instanceof验证某个东西是不是数组,其实就是验证有没有数组的prototype.

let arr=[1,2,3]
arr instanceof Array //true
arr instanceof Object //true

上面代码中,arr实例对象的原型链中包含Array和Object的原型,所以返回的都是true。

参数为简单数据类型

当Object函数的参数为简单数据类型时,那么会包装成对应的包装对象的实例

let a =Object(1) //Number{1}
let b =Object('1') //String{'1'}
a instanceof Object //true
a instanceof Number //true

当参数为复杂数据类型

当参数是普通实例对象、数组对象、函数时,那么会返回原来的数据

let a ={name:1}
let b =Object(a)
a === b //true

所以这种方法可以判断变量是否为对象。

new Object构造函数

当使用new Object时,会生成一个新对象,

Object跟new Object用法几乎一样,当参数为复杂数据类型时,会返回原来的数据。当参数为简单数据类型时,则会包装成对应的包装对象的实例。

在语义上Object函数是用来将某个value转成对象,而new Object是新生成一个对象,值是value。

Object静态方法

所谓静态方法,是指的定义在Object身上的方法,它不能被其实例对象所调用。

为了了解这一点,我们可以模拟一个Object构造函数

function Object(){
	this.name=Object,
    this.say=()=>{console.log('加了this的都可以被实例对象调用')}
}
Object.sing=function (){console.log('我不在prototype上,我是静态方法')}
let obj =new Object()
obj.say() // Object 可以被实例对象调用
obj.sing() // Uncaught TypeError: obj.sing is not a function

上面的代码模拟出Object的构造函数,Object.sing定义只属于Object函数的方法,只有它能够访问。

Object.keys()和Object.getOwnPropertyNames()

Object.keys方法和Object.getOwnPropertyNames方法都用来遍历对象的属性。

Object.keys方法的参数是一个对象,返回一个数组。该数组的成员都是该对象自身的(而不是继承的)所有属性名

Object.getOwnPropertyNames方法跟Object.keys方法几乎使用是一样的,但是区别在于它还可以遍历对象中不可枚举的属性,例如数组对象中的length属性就属于不可枚举属性。

let arr=[1,2,3]
Object.keys(arr) //["0", "1", "2"]
Object.getOwnPropertyNames(arr ) //["0", "1", "2", "length"]

Object实例方法

实例方法主要是定义在Object.prototype上,所有的实例都可以自己调用这些方法。

Object.prototype.toString 判断数据类型

var obj={}
obg.toString() // "[object Object]"

返回的值里面第二个是该值的构造函数,所以我们可以用来判断某变量的细化数据类型。

由于实例对象会自定toString方法,例如Array.prorotype.toString方法,所以使用数组是不能直接使用arr.toString来判断细化后的数据类型的,我们应当使用Object.prototype.toString的方式加个call来实现调用。

[].toString() //这里调用的是Array.prorotype.toString方法 所以返回 ''
Object.prototype.toString.call([]) //"[object Array]"

利用这个特性,我们可以写一个更精细判断数据类型的函数。

    var type = function (o){
      var s = Object.prototype.toString.call(o);
      return s.match(/\[object (.*?)\]/)[1].toLowerCase();
    };

    type({}); // "object"
    type([]); // "array"
    type(5); // "number"
    type(null); // "null"
    type(); // "undefined"
    type(/abcd/); // "regex"
    type(new Date()); // "date"

Object.prototype.hasOwnProperty()判断是否具有自有属性

Object.prototype.hasOwnProperty()方法可以接受一个字符串参数来判断是否为对象自有属性,返回true或者false。注意这里判断的是属性而不是属性值。

var arr =[1,2,3]
arr.hasOwnProperty('3') //false
var obj={name:`objname`}
Object.prototype.hasOwnProperty.call(obj,'name') //true
obj.hasOwnProperty('toString') //false

上面代码中因为数组arr没有3这个下标,所以返回false

obj的自有属性只有name,toString是其原型链上的方法,所以分别返回true和false

参考资料:

网道(WangDoc.com),互联网文档计划