在学习Es6的时候,发现了很多object这个对象的方法,但是却没有系统学习一下,所以上MDN学习一下。
为什么实例对象能用Object.prototype的方法呢,因为在实例对象中找不到这个方法,就会到他继承的函数上面找,最后找到Object.prototype
这个对象。
constructor返回的是该对象的构造函数
<script type="text/javascript">
var test=new Array();
if (test.constructor==Array)
{
document.write("This is an Array");
}
if (test.constructor==Boolean)
{
document.write("This is a Boolean");
}
if (test.constructor==Date)
{
document.write("This is a Date");
}
if (test.constructor==String)
{
document.write("This is a String");
}
</script>
hasOwnProperty() 方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键)。
该方法会忽略到原型上面继承的属性。
const object1 = new Object(); object1.property1 = 42;
console.log(object1.hasOwnProperty('property1')); // expected output: true
console.log(object1.hasOwnProperty('toString')); // expected output: false
可以用这个来过滤掉for in 会遍历继承的属性,只遍历原属性
还有这个属性是可以设置的,所以担心原属性被设置,可以用call,来改变this指向
// 如果担心这种情况,
// 可以直接使用原型链上真正的 hasOwnProperty 方法
({}).hasOwnProperty.call(foo, 'bar'); // true
// 也可以使用 Object 原型上的 hasOwnProperty 属性
Object.prototype.hasOwnProperty.call(foo, 'bar'); // true
isPrototypeOf() 方法允许你检查一个对象是否存在于另一个对象的原型链上。
在这里补充一下枚举的相关信息
- for…in循环
- Object.keys方法
- JSON.stringify方法
这三个会自动过滤掉枚举的属性
enumerable “隐身术”
var o = {a:1, b:2};
o.c = 3;
Object.defineProperty(o, 'd', { //用object.defineProperty来定义属性可以设置属性的值和是否可枚举
value: 4,
enumerable: false
});
o.d
// 4
for( var key in o ) console.log( o[key] );
// 1
// 2
// 3
Object.keys(o) // ["a", "b", "c"]
JSON.stringify(o // => "{a:1,b:2,c:3}"
propertyIsEnumerable() 方法返回一个布尔值,表示指定的属性是否可枚举。
toString() 方法返回一个表示该对象的字符串。
valueOf() 方法返回指定对象的原始值。
Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
console.log(target);
// expected output: Object { a: 1, b: 4, c: 5 }
console.log(returnedTarget);
// expected output: Object { a: 1, b: 4, c: 5 }
合并对象在数据交互的时候使用的最多,post方式需要上传很多参数,从而用这个方法了合并参数,但是具有相同属性的属性会被后者
覆盖。
同时继承属性和不可枚举属性是不能拷贝的。
//Es5之前的实现方法
if (typeof Object.assign != 'function') {
// 判断是否是已经存在这个函数
Object.defineProperty(Object, "assign", {
//定义这个属性
value: function assign(target, varArgs) { // .length of function is 2
'use strict';
if (target == null) { // TypeError if undefined or null
throw new TypeError('Cannot convert undefined or null to object');
}
let to = Object(target);
//遍历传入来的参数
for (var index = 1; index < arguments.length; index++) {
var nextSource = arguments[index];
if (nextSource != null) { // Skip over if undefined or null
for (let nextKey in nextSource) {
// 判断是否是继承的元素,不是继承菜遍历,但是这一步的属性如果是引用类型的话,只能指向,一改动也还是会变动。
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
to[nextKey] = nextSource[nextKey];
}
}
}
}
return to;
},
writable: true,
configurable: true
});
}
Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。
Object.creat 与new的区别,new的话,因为必须要有构造函数,所以构造函数的实例会获取到构造函数的属性和方法,而creat不会用到构造函数函数的属性,这里的话又得了解一下new的过程了,new是创建一个新对象,将obj的proto指向构造函数的原型,然后让构造函数的this指向obj,并执行构造函数,返回this,在这里的时候就调用了一次构造函数,生成了一份构造函数的属性,在继承哪里已经用call继承属性,所以就又调用了一下,而creat的话并没有,这样的话也就是实现寄生组合继承的方法,就如下面的继承一样,用create实现寄生组合继承。
function Student(name, sex, age) {
Person.call(this, name, sex);//这里的理解,调用了person的构造函数,在this绑定属性的时候,this的指向的是students的实例,
通过这种方法给students继承父亲的属性。
this.age = age;
}
//原型链拼接
Student.prototype = Object.create(Person.prototype);//这里面会生成一个F()实例来获取Person的实例,然后返回这个实例,但是会
改变原型构造函数指向,所以需要纠正,但是就不会获取构造函数本身的属性,因为不需要再new一个构造函数。
//构造函数弯了,纠正
Student.prototype.constructor = Student;
Student.prototype.getInfo = function() {
console.log('getInfo: [name:' + this.name + ', sex:' + this.sex + ', age:' +this.age + '].');
}
var s = new Student('coco', 'femal', 25);
Object.defineProperty()和Object.definePropertys()两个在下面链接,解释的很好。
还有Object.getOwnPropertyDescriptor()
Object. getOwnPropertyDescriptors()
https://segmentfault.com/a/1190000011294519?utm_source=tag-newest
这里也很好的写了vue双向绑定的原理。
Object.getOwnPropertyNames()方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。
Object.getPrototypeOf() 获取对象的原型
Object.setPrototypeOf(object, prototype)用来设置对象原型
Object.is()判断两个值是不是相同的值
Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用 for…in 循环遍历该对象时返回的顺序一致 。如果对象的键-值都不可枚举,那么将返回由键组成的数组。
如果属性是Number的话,就按照从小到大排序,如果是字符的symbol的话,就按照创造时间排序。