Object
在看 ES6 Object的时候,我发觉ES5 Object 的更新我并不是完全知道。
于是觉得还是看一下.
1. __proto__
作为一个 半吊子前端开发人员. 居然不知道这个..
首先这个 MSDN 上的例子
function Rectangle() {
}
var rec = new Rectangle();
if (console && console.log) {
console.log(rec.__proto__ === Rectangle.prototype); // Returns true
rec.__proto__ = Object.prototype;
console.log(rec.__proto__ === Rectangle.prototype); // Returns false
}
然后我发现。 貌似这个就是原型链。
只不过以前是隐藏的现在将他公布出来。
他指向构造函数的 prototype
.
例如这样
function a() { };
a.prototype.haha = 10;
a.prototype.haha1 = 11;
var a1 = new a();
h.w(a1.__proto__);
//constructor:a()
//haha:10
//haha1:11
//haha2:20
a1.__proto__.haha2 = 20;
h.w(a1.haha);
h.w(a1.haha1);
h.w(a1.haha2);
h.w(a1.__proto__);
//constructor:a()
//haha:10
//haha1:11
//haha2:20
这边其实是有些疑问的.
比如 haha
& haha1
是并不存在于 a1.__proto__
中.
理论上是 在 a1.__proto__
中找不到 向上层 prototype
中寻找
但是输出的时候却看得见。
还有就是
在第一次执行 h.w(a1.__proto__);
的时候
确输出了 haha2
. 这个应该是在第二次执行的输出的时候才有的啊。
于是在加了一段代码.
function a() { };
a.prototype.haha = 10;
a.prototype.haha1 = 11;
var a1 = new a();
h.w(a1.__proto__);
h.w(a1.haha2); //undefined.
a1.__proto__.haha2 = 20;
h.w(a1.haha);
h.w(a1.haha1);
h.w(a1.haha2);
h.w(a1.__proto__);
所以我不知道 chrome 在搞什么...
但是能确定的是 __proto__
就是原型链。
所以.
var o = {}; // o = new Object()
o.__proto__ === Object.prototype
2. Object.assign
var target = { a: 1 };
var source1 = { b: 2 };
var source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}
简单说就是合并。
如果有相同的值以后面为准
首先需要注意的是,复制的问题。
多层嵌套以后,他是直接复制的.
var target4 = {a: 1};
var target5 = Object.assign({}, target4);
target5.a = 2;
h.w(target4); //1
var target = { a: 1,b:{ b1:1 } };
var target1 = Object.assign({},target);
target1.a = 2;
target1.b.b1 = 2;
h.w(target.a); //1
h.w(target.b.b1); //2
所以如果你想复制一个 Object
var target = { a: 1,b:{ b1:1 } };
var target1 = Object.assign({},target);
有多层嵌套的肯定不行。
assign
一些特殊的传入值
try{
Object.assign(undefined);
Object.assign(null);
}
catch(ex) {
h.w(ex.name + ":" + ex.message)
//TypeError:Cannot convert undefined or null to object
}
h.w(Object.assign(2)); //Number {[[PrimitiveValue]]: 2}
h.w(Object.assign("haha")); //String {0: "h", 1: "a", 2: "h", 3: "a", length: 4, [[PrimitiveValue]]: "haha"}
h.w(Object.assign({a:1})); //Object {a: 1}
h.w(Object.assign({},true)); //Object {}
h.w(Object.assign({},"aaa","bbb")); //Object {0: "b", 1: "b", 2: "b"}
h.w(Object.assign({},10)); //Object {}
3 Object.create
var o = Object.create({a:1}, {
size: {
value: "large",
enumerable: true
},
shape: {
value: "round",
enumerable: true
}
});
h.w(o.a);
h.w(o.size);
h.w(o.shape);
这个是微软的例子
在我的理解已经很说明问题了。
第一个参数 就是原型链继承。
function a() {}
a.prototype = 第一个参数
return new a()
第二个参数我感觉像是 this
不过我不能100%确定..
4. defineProperty & defineProperties
Object.defineProperty(object, propertyname, descriptor)
object
必需。 要在其上添加或修改属性的对象。 这可能是一个本机 JavaScript 对象(即用户定义的对象或内置对象)或 DOM 对象。
propertyname
必需。 一个包含属性名称的字符串。
descriptor
必需。 属性描述符。 它可以针对数据属性或访问器属性。
// Create a user-defined object.
var obj = {};
// Add a data property to the object.
Object.defineProperty(obj, "newDataProperty", {
value: 101,
writable: true,
enumerable: true,
configurable: true
});
// Set the property value.
obj.newDataProperty = 102;
document.write("Property value: " + obj.newDataProperty + newLine);
value 默认值
writable 是否可写
enumerable 可枚举
configurable 是否可删除
set 写的接口
get 读的接口
大概就这些。
但是里面还是有不少东西值得注意
var obj = {};
// Add a data property to the object.
Object.defineProperty(obj, "newDataProperty", {
value: 101
});
obj.newDataProperty = 100;
h.w(obj.newDataProperty); //101
比如加上 value
这个默认值, 似乎就会加上 writable = false
修改不了,除非你显示声明了 writable = true
configurable
也就是说 delete obj.newDataProperty
不会再有效了。
enumerable
.
var obj1 = { a:1 };
// Add a data property to the object.
Object.defineProperty(obj1, "newDataProperty", {
value: 101,
enumerable:false
});
for(var key in obj1)
h.w(key);
set,get
这个比较简单。 就是提供了一个方法而已.
Object.defineProperty(obj, "newAccessorProperty", {
set: function (x) {
document.write("in property set accessor" + newLine);
this.newaccpropvalue = x;
},
get: function () {
document.write("in property get accessor" + newLine);
return this.newaccpropvalue;
},
enumerable: true,
configurable: true
});
最后 defineProperties
就是多一层 嵌套。 可以一次写多个。
var obj = {};
Object.defineProperties(obj, {
newDataProperty: {
value: 101,
writable: true,
enumerable: true,
configurable: true
},
newAccessorProperty: {
set: function (x) {
document.write("in property set accessor" + newLine);
this.newaccpropvalue = x;
},
get: function () {
document.write("in property get accessor" + newLine);
return this.newaccpropvalue;
},
enumerable: true,
configurable: true
}});
也可以生成好以后 传进去
var obj = {};
var descriptors = { xxx : {value:1 }};
Object.defineProperties(obj, descriptors)
5. Object.freeze(object)
冻结。
其实也就是通过 defineProperty
将除了 enumerable
所有属性设置为false.
6.getOwnPropertyDescriptor && getOwnPropertyDescriptors
var o = { a:1 };
var keys = Object.getOwnPropertyDescriptor(o,"a");
h.w(keys);
configurable:true
enumerable:true
value:1
writable:true
Object.freeze(o);
var keys1 = Object.getOwnPropertyDescriptor(o,"a");
h.w(keys1);
configurable:false
enumerable:true
value:1
writable:false
其实就是返回某一个字段 属性。
然后你可以修改了以后 再赋给 字段...
所以说。 给 object 增加了 属性 也不是绝对的安全啊 哈哈哈
getOwnPropertyDescriptors
是ES7的提案。
可以一次返回所有 不用一个一个字段来弄.
7. getOwnPropertyNames
function Pasta(grain, width, shape) {
// Define properties.
this.grain = grain;
this.width = width;
this.shape = shape;
this.toString = function () {
return (this.grain + ", " + this.width + ", " + this.shape);
}
}
Pasta.prototype.test = "haha";
// Create an object.
var spaghetti = new Pasta("wheat", 0.2, "circle");
// Get the own property names.
var arr = Object.getOwnPropertyNames(spaghetti);
document.write (arr);
// Output:
// grain,width,shape,toString
上面这个是微软的例子。 就是遍历 属性
很简单,但是他很好玩的是
var o = { a:1 }
Object.defineProperty(o,'haha',{
enumerable:false,
value:2
});
var arr1 = Object.getOwnPropertyNames(o);
h.w(arr1);
他无视了 enumerable
8. getPrototypeOf 获取原型链
var a = function() {}
h.w(a.prototype == Object.getPrototypeOf(a)); //false
var b = new a();
h.w(b.__proto__ == Object.getPrototypeOf(b)) //true
9. Object.is
主要是用来规避
h.w(+0 === -0); //true
h.w(NaN === NaN); //false
h.w(Object.is(+0,-0)); //false
h.w(Object.is(NaN,NaN)); //true
其他一样
10. isExtensible isSealed isFrozen
https://msdn.microsoft.com/zh-cn/library/ff806189(v=vs.94).aspx
https://msdn.microsoft.com/zh-cn/library/ff806185(v=vs.94).aspx
https://msdn.microsoft.com/zh-cn/library/ff806188(v=vs.94).aspx
这三个真的木有什么好讲的..
Object.preventExtensions 设置不可扩展
Object.seal 设置是否 configurable
标题三个 就是来检测是否设置了。
11.Object.Keys
感觉和 getOwnPropertyNames
一模一样.
只不过
var o = { a:1 }
Object.defineProperty(o,'haha',{
enumerable:false,
value:2
});
h.w(Object.keys(o))
enumerable 有用了