笔记-你不知道的JS-对象

1 怎样定义

// 声明情势,大部分情况下运用声明情势
let obj ={
  a:2,
  b:3
};
// 组织情势
let obj= = new Object();
obj.a=2;
obj.b=3;

2 范例

7种范例:string、boolean、number、null 、 undefined、object、symbol

typeof null === object,道理是如许的,差别的对象在底层都示意为二进制,在 JavaScript 中二进制前三位都为 0 的话会被推断为 object 范例,null 的二进制示意是全 0,天然前三位也是 0,所以实行 typeof 时会返回“object”。

内置对象:String, Number, Object, Date, Boolean, Array, Function, RegExp, Error,在 JavaScript 中,它们实际上只是一些内置函数。这些内置函数能够看成组织函数,运用 new 挪用,发生新对象。

在必要时言语会自动把字符串字面量转换成一个 String 对象,也就是说你并不需要显式建立一个对象。

var strPrimitive = "I am a string"; 
console.log( strPrimitive.length ); // 13 
console.log( strPrimitive.charAt( 3 ) ); // "m"

我们都能够直接在字符串字面量上接见属性或许要领,之所以能够如许做,是由于引擎自动把字面量转换成 String 对象,所以能够接见属性和要领。一样引擎会自动把数字字面量转换为Number对象,如运用3.1415.toFixed(2)

null 和 undefined 没有对应的组织情势,它们只要笔墨情势。相反,Date 只要组织,没有笔墨情势。
关于 Object、Array、Function 和 RegExp(正则表达式)来讲,不论运用笔墨情势照样组织情势,它们都是对象,不是字面量。

Error 对象很少在代码中显式建立,平常是在抛出非常时被自动建立。也能够运用 newError(..) 这类组织情势来建立。

3 属性

. 操纵符要求属性名满足标识符的定名范例。

在对象中,属性名永远都是字符串。假如你运用 string(字面量)之外的其他值作为属性名,那它起首会被转换为一个字符串。

var myObject = { };
let arr = [2,3];
myObject[true] = "foo"; 
myObject[3] = "bar"; 
myObject[myObject] = "baz";
myObject[arr] =4;
myObject["true"]; // "foo"
myObject["3"]; // "bar"
myObject["[object Object]"]; // “baz”
myObject["2,3"]; // 4

为数组增加定名属性,但数组的length值不会变

4 复制

关于 JSON 平安(也就是说能够被序列化为一个 JSON 字符串而且能够依据这个字符串解析出一个构造和值完整一样的对象)的对象来讲,有一种奇妙的复制要领:

var newObj = JSON.parse( JSON.stringify( someObj ) );
Object.assign(..) 要领的第一个参数是目的对象,以后还能够跟一个或多个源对象。它会遍历一个或多个源对象的一切可罗列(enumerable,拜见下面的代码)的自有键(owned key,很快会引见)并把它们复制(运用 = 操纵符赋值)到目的对象,末了返回目的对象。

5 属性描述符

var myObject = { a:2};
Object.getOwnPropertyDescriptor( myObject, "a" );
// {
// value: 2,
// writable: true,
// enumerable: true,
// configurable: true 
// }
// writable(可写)、 enumerable(可罗列)和 configurable(可设置)

不论是不是是处于严厉形式,尝试修正一个不可设置的属性描述符都邑失足,也不能够删除该属性。注重:如你所见,把 configurable 修正成false 是单向操纵,没法打消!要注重有一个小小的破例:即使属性是 configurable:false,我们照样能够把 writable 的状况由 true 改成 false,然则没法由 false 改成 true。

enumerable描述符掌握的是属性是不是会出如今对象的属性罗列中,比如说for..in 轮回。假如把 enumerable 设置成 false,这个属性就不会出如今罗列中,虽然依然能够一般接见它。

6 不变性

1 连系 writable:false 和 configurable:false 就能够建立一个真正的常量属性

2 假如你想制止一个对象增加新属性而且保存已有属性,能够运用 Object.preventExtensions(..)

3 Object.seal(..) 会建立一个“密封”的对象,这个要领实际上会在一个现有对象上挪用Object.preventExtensions(..) 并把一切现有属性标记为 configurable:false。所以,密封以后不仅不能增加新属性,也不能重新设置或许删除任何现有属性(虽然能够修正属性的值)。

4 Object.freeze(..) 会建立一个凝结对象,这个要领实际上会在一个现有对象上挪用Object.seal(..) 并把一切“数据接见”属性标记为 writable:false,如许就没法修正它们的值。你能够“深度凝结”一个对象,具体要领为,起首在这个对象上挪用 Object.freeze(..),然后遍历它援用的一切对象并在这些对象上挪用 Object.freeze(..)。然则一定要警惕,由于如许做有能够会在无意中凝结其他(同享)对象。

7 [[Get]]和[[Put]]

在言语范例中,myObject.a 在 myObject 上实际上是完成了 [[Get]] 操纵(有点像函数挪用:[[Get]]())。对象默许的内置 [[Get]] 操纵起首在对象中查找是不是有称号雷同的属性,假如找到就会返回这个属性的值。假如没有找到称号雷同的属性,会遍历能够存在的 [[Prototype]] 链,也就是原型链。若在原型链上也没有找到,那就返回undefined。

[[Put]] 被触发时,假如已存在这个属性,[[Put]] 算法大抵会搜检下面这些内容。

  1. 属性是不是是接见描述符(拜见3.3.9节)?假如是而且存在setter就挪用setter。
  2. 属性的数据描述符中writable是不是是false?假如是,在非严厉形式下寂静失利,在严厉形式下抛出 TypeError 非常。
  3. 假如都不是,将该值设置为属性的值。

假如对象中不存在这个属性,[[Put]] 操纵会越发庞杂。

8 存在性

in 操纵符会搜检属性是不是在对象及其 [[Prototype]] 原型链中。

hasOwnProperty(..) 只会搜检属性是不是在 myObject 对象中,不会搜检 [[Prototype]] 链。

一切的一般对象都能够经由过程关于 Object.prototype 的托付来接见hasOwnProperty(..), 但 是 有 的 对 象 可 能 没 有 连 接 到 Object.prototype( 通 过Object.create(null) 来建立)。在这类情况下,形如 myObejct.hasOwnProperty(..)就会失利。这时候能够运用Object.prototype.hasOwnProperty.
call(myObject,”a”)。

9 遍历

for..in 轮回能够用来遍历对象的可罗列属性列表(包含 [[Prototype]] 链)。

关于数值索引的数组来讲,能够运用规范的 for 轮回来遍历值,或许运用for…of轮回,for..of 轮回起首会向被接见对象要求一个迭代器对象,然后经由过程挪用迭代器对象的next() 要领来遍历一切返回值。

    原文作者:小利子
    原文地址: https://segmentfault.com/a/1190000019376733
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞