你不知道的js - 对象

一、对象有两种形式定义:声明文字形式和构造形式。数组

二、内置对象:js中有一些对象子类型,称为内置对象安全

var strprimitive = 'I am string';
typeof strprimitive;//'string'
strprimitive instanceof String; //false

var strobj = new String('I am string');
typeof strobj;
strobj instanceof String;

Object.prototype.toString.call(strobj); // [object string]

 typeof ,instanceof,Object.prototype.toString.call()区分对象类型函数

js中经过Object.prototype.toString方法----精确判断对象的类型

一、在 JavaScript 里使用 typeof 来判断数据类型,只能区分基本类型,即 “number”,”string”,”undefined”,”boolean”,”object” 五种。spa

对于数组、函数、对象来讲,其关系错综复杂,使用 typeof 都会统一返回 “object” 字符串。prototype

二、instanceof判断对象类型,有点麻烦code

//对象
(a instanceof Object) && !(a instanceof Array) && !(a instanceof Function)
//数组
(a instanceof Object) && (a instanceof Array)
//函数
(a instanceof Object) && (a instanceof Function)

三、使用Object.prototype.toString方法对象

console.log(Object.prototype.toString.call("jerry"));//[object String]
console.log(Object.prototype.toString.call(12));//[object Number]
console.log(Object.prototype.toString.call(true));//[object Boolean]
console.log(Object.prototype.toString.call(undefined));//[object Undefined]
console.log(Object.prototype.toString.call(null));//[object Null]
console.log(Object.prototype.toString.call({name: "jerry"}));//[object Object]
console.log(Object.prototype.toString.call(function(){}));//[object Function]
console.log(Object.prototype.toString.call([]));//[object Array]
console.log(Object.prototype.toString.call(new Date));//[object Date]
console.log(Object.prototype.toString.call(/\d/));//[object RegExp]

全部类型都会获得不一样的字符串,几乎完美。blog

 

那为何不直接用obj.toString()呢?索引

这是由于toString为Object的原型方法,而Array ,function等类型做为Object的实例,都重写了toString方法。不一样的对象类型调用toString方法时,根据原型链的知识,调用的是对应的重写以后的toString方法(function类型返回内容为函数体的字符串,Array类型返回元素组成的字符串.....),而不会去调用Object上原型toString方法(返回对象的具体类型),因此采用obj.toString()不能获得其对象类型,只能将obj转换为字符串类型;所以,在想要获得对象的具体类型时,应该调用Object上原型toString方法。 ip

 四、内容

 

 var myObject = {
  a:2
 };
 myObject.a;//2
 myObject['a'];//2

 

若是要访问myObject 中a位置上的值,咱们须要使用.操做符,或者[]操做符

.a语法一般被称做属性访问,['a']语法一般被称为键访问

区别在于.操做符要求属性名知足标识符的命名规范,而[..]语法能够接受任意UTF-8/Unicode字符串做为属性名

因为[..]语法使用字符串来访问属性,因此能够在程序中构造字符串

在对象中属性名永远是字符串

五、可计算属性名

ES6增长了可计算属性名,能够在文字形式中使用[]包裹一个表达式看成属性名。

 var prefix = "foo";
 var myObject = {
  [prefix+"bar"]:'hello',
  [prefix+"baz"]:'world'
 };
 myObject['foobar'];//hello
 myObject['foobaz'];//world

 六、数组

数组指望的是数值下标,也就是说值存储的位置是非负整数

数组也是对象,因此虽然每一个下标都是整数,仍然能够给数组添加属性

 var myArray = ['foo',42,'bar'];
 myArray.baz = 'baz';
 myArray.length;//3
 myArray.baz;//'baz'

能够看到虽然添加了命名属性,数组的length值并无发生变化

若是你试图向数组中添加一个属性可是属性名看起来很像一个数字,那它会变成一个数值下标

var myArray = ['foo',42,'bar'];
myArray['3'] = 'baz';
myArray.length;//4
myArray[3];//'baz'

七、复制对象

对于JSON安全的对象来讲,有一种巧妙的复制方法:

JSON安全:也就是说能够被序列化为一个JSON字符串而且能够根据这个字符串解析出一个结构和值彻底同样的对象

var newObj = JSON.parse(JSON.stringfy(someObj));

这种方法须要保证对象是JSON安全的,因此只适用于部分状况

浅复制易懂,问题少一些。

Object.assign(..)第一个参数是目标对象,以后能够跟一个或多个源对象

八、属性描述符

从ES5开始,全部属性都具备了属性描述符

var myObject = {
  a:2
}
Object.getOwnPropertyDescriptor(myObject,'a');

// {
// value: 2,
// writable: true,
// enumerable: true,
// configurable: true
// }

 可使用Object.defineProperty()来添加一个新属性,或者修改一个已有属性

Object.defineProperty(myObject,'a',{
    value: 2,
    writable: true,
    enumerable: true,
    configurable: true
});
myObject.a;//2

九、对象默认的[[Put]] 和[[Get]]操做分别能够控制属性值的设置和

在ES5中可使用getter和setter部分改写默认操做,可是只能应用在单个属性上,没法应用在整个对象上。getter是一个隐藏函数,会在获取属性值时调用,setter也是一个隐藏函数,会在设置属性时调用。

var myObject = {
  get a() {
    return 2;
  }
};
myObject.a = 3;
myObject.a;//2

因为咱们只定义了a的getter,因此对a的值进行设置时,set操做会忽略赋值操做,不会抛出错误。

即便有了合法的setter咱们定义的getter只会返回2。因此set操做没有意义。

十、存在性

咱们能够在不访问属性值的状况下判断对象中是否存在这个属性

var myObject = {
  a:2
};
('a' in myObject);//true
('b' in myObject);//false

myObject.hasOwnProperty('a');// true
myObject.hasOwnProperty('b');//false

in 操做符会检查属性是否在对象及其[[Prototype]]原型链上,相比之下,hasOwnProperty()只会检查属性是否在myObject对象中,不会检查[[Prototype]]链

注意:in实际上检查的是某个属性是否存在。对于数组:4 in [2,4,6] 并非true ,由于 [2,4,6] 包含的是属性名0,1,2没有4

 十一、枚举

可枚举就至关于 能够出如今对象属性的遍历中

不影响存在性

for...in...这种枚举不只会包含全部的数值索引还会包含全部可枚举属性

相关文章
相关标签/搜索