在js运行时,原生对象的描述方式非常简单,我们只需要关心原型和属性两个部分。。
js中的对象中的属性(property)既可以描述状态,又可以表示行为,因为函数可以放进属性中。
js中的object的唯一标识是用内存地址的唯一性。
对象中的属性(property)是用key-value对表示的。key可以用string和symbol两种类型来定义。string类型就是大家都可以懂的那种,不管你的string写的多么的奇怪,总可以用string来get到属性值。但是symbol不一样,symbol只能通过变量去引用它,我们是不能去构建两个一模一样的symbol的。两个symbol即使名字一样,实际上也是不一样的。如果你不把symbol这个变量告诉它呢,那么你这段代码的使用者没有办法访问你用symbol变量作为key的属性的值得。
属性的value有两种形态,一种是数据形态(data property),另一种是访问器形态(accesstor property)。
数据属性:一般用于描述状态,如果数据属性存储函数,那么它也可以描述行为。它有四个特征值(attribute):value
、writable
、enumerable
和configurable
。
如果configurable=false
,则四个attribute都不可变。
如果writable=false
,仅仅是通过点运算不可改变value,但是可以通过define property
去改变writable
强行改变value
。
访问器属性:用于描述行为。它有四个特征值(attribute):get
、set
、enumerable
和configurable
。get
和set
就是通过点运算去读或写时来调用的。enumerable主要影响的是object.keys()
这样的一些内置的函数的行为和forEach
这样的语法产生的一些行为。
原型机制:
当我们去找一个对象的属性的时候,如果它自己没有,就会去原型去找。如果原型的原型不为空的话,就到它的原型的原型上去找,形成了一个链式的行为,直到原型为空。这就是原型链。
特殊对象
1.函数对象(function)
函数的typeof
不是object
而是function
.
除了一般对象的属性和行为,函数对象还有一个行为 call
。用js中的function关键字、箭头运算符或者function构造器创建的对象都会有call
这个行为。用类似f()
这样的语法把对象当做函数调用的时候,会访问到call
这个行为。如果对应的对象没有call
行为,就会报错。
2.数组
length
属性会改变
3.object.prototype
他是所有对象的原型,没有setPrototypeOf
方法。
4. host object
js本身没有的对象,而是宿主环境中的变量,比如浏览器中的window
, setTimeout
,这种对象可以实现js语言中不支持单数js语法支持的一些特性,比如foo()=2;
但是这很脑残,所以就没有这么用的。语法是语法,运行时时运行时。他们也可以实现[[call]
和[[construct]]
方法的,但是在js代码不能调用,再试在调用js引擎的c代码或者c++代码中是可以调用到的。