《你不知道的JavaScript》读书笔记(三)

对象

对象可以通过两种方式定义:生命(文字)形式和构造形式。

类型

六种主要类型:string、boolean、number、null、undefined和object。
typeof null 会返回字符串“object”,这是一个bug。

原理是这样的,不同对象在底层都表示为二进制,在JavaScript中二进制前三位都是0的话会被判断为object类型,null的二进制表示全为0,自然前三位也是0,所以执行typeof时会返回“object”。

内置对象

  • String
  • Number
  • Boolean
  • Object
  • Function
  • Array
  • Date
  • RegExp
  • Error

这些内置对象从表现形式来说很像其他语言中的类型(type)或者类(class),比如Java中的String类。
这些内置函数可以当做构造函数使用,从而可以构造一个对应子类型的新对象。例如:

1
2
3
4
5
6
7
var strPrimitive = "I am a string";
typeof strPrimitive; //"string"
strPrimitive instanceof String; //false

var strObject = new Object("I am a string");
typeof strObject; =>"object"
strObject instanceof String; //true

内容

访问属性有两种方式:“属性访问”和“键访问”。

1
2
3
4
5
6
var myObject = {
a: 2
};

myObject.a; //2
myObject["a"]; //2

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

属性和方法

函数不会“属于”一个对象————它们只是对于相同函数对象的多个引用。

复制对象

这里涉及到浅复制深复制

属性描述符

1
2
3
4
5
var myObject = {
a: 2
}
Object.getOwnPropertyDescriptor(myObject, "a");
//{value: 2, writable: true, enumerable: true, configurable: true}

writable(可写)、enumerable(可枚举)和configurable(可配置)。

通过使用Object.defineProrerty(..)来添加一个新属性或者修改一个已有属性(如果他是configurable)并对特性进行设置。

不变性

1.对象常量
结合writable:falseconfigurable:false就可以创建一个真正的常量属性(不可修改、重定义或者删除)
2.禁止扩展
使用Object.preventExtensions(..)可以禁止一个对象添加新属性并且保留已有属性。
3.密封
Object.seal(..)会创建一个“密封”对象,这个方法实际上会在一个现有对象上调用Object.prenvenExtensions(..)并把所有现有属性标记为configurable:false。与禁止扩展不同的是,“密封”后不能重新配置任何现有属性。
4.冻结
Object.freeze(..)相当于调用Object.seal(..)之后并把所有的“数据访问”属性标记为writable:false

存在性

myObject.a的属性访问返回值可能是undefined,但是这个值有可能是属性中存储的undefined,也可能是因为属性不存在所以返回undefined。如何区分这两种情况呢?

1
2
3
4
5
6
7
8
9
var myObject = {
a: 2
};

("a" in myObject); // ture;
("b" in myObject); // false;

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

不同的是in会访问原型链,hasOwnProperty(..)不会检查原型链。
Object.propertyIsEnumerable(..)会检查给定的属性名是否直接存在于对象中并且满足emumerable:true
Object.keys(..)会返回一个数组,包含所有可枚举属性;
Object.getOwnPropertyNames(..)返回一个数组,包含所有属性,无论他们是否可枚举。

0%