Javascript对象的特征
- 对象具有唯一标识性:即使完全相同的两个对象,也并非同一个对象。(每个对象的内存地址不同)
- 对象有状态:对象具有状态,同一个对象可能处于不同状态之下。
- 对象具有行为:即对象的状态,可能因为他的行为产生变迁。
- 对象的状态和行为都是用属性来抽象的。
Javascript对象的两类属性
数据属性
- value:属性的值
- writable:决定属性能否被赋值
- enumerable:决定for in能否枚举该属性
- configurable:决定该属性能否被删除或者改变特征值
访问器属性
- getter:函数或者undefined,在取属性值时被调用
- setter:函数或者undefined,在设置属性值时被调用
- enumerable:决定for in能否枚举该属性
- configurable:决定该属性能否被删除或者改变特征值
我们可以使用getOwnPropertyDescriptor来查看属性状态
var o = { a: 1 };
o.b = 2;
//a 和 b 皆为数据属性
Object.getOwnPropertyDescriptor(o,"a") // {value: 1, writable: true, enumerable: true, configurable: true}
Object.getOwnPropertyDescriptor(o,"b") // {value: 2, writable: true, enumerable: true, configurable: true}
复制代码
如果想改变属性的特征或者定义访问器属性可以使用Object.defineProperty
var o = { a: 1 };
Object.defineProperty(o, "b", {value: 2, writable: false, enumerable: false, configurable: true});
//a 和 b 都是数据属性,但特征值变化了
Object.getOwnPropertyDescriptor(o,"a"); // {value: 1, writable: true, enumerable: true, configurable: true}
Object.getOwnPropertyDescriptor(o,"b"); // {value: 2, writable: false, enumerable: false, configurable: true}
o.b = 3;
console.log(o.b); // 2
复制代码
同样也可以使用get或者set来创建访问器属性
var o = { get a() { return 1 } };
console.log(o.a); // 1
复制代码
Javascript的原型
- 所有对象都有一个私有字段[[prototype]],就是对象的原型
- 读一个属性,如果对象本身没有,则会继续访问对象的原型,直到原型为空或者找到为止。
- Object.create 根据指定的原型创建新对象,原型可以是null
- Object.getPrototypeOf 获取一个对象的原型
- Object.setPrototypeOf 设置一个对象的原型
new的整体实现过程
- 以构造器的prototype属性为原型,创建新对象。
- 将this和调用参数传给构造器,执行
- 如果构造器返回的是对象,则返回,否则返回第一步创建的对象。
function mynew(){
let obj = {};
let con = [].shift.call(arguments)
obj.__proto__ = con.prototype;
let r = con.call(obj,arguments)
return r instanceof Object ? r : obj;
}
复制代码
Object.create的实现
- 不支持第二个参数
- 不支持null作为原型
Object.create = function(prototype){
var cls = function(){}
cls.prototype = prototype;
return new cls;
}
复制代码