Object静态方法

Object自身方法,必须由Object调用,实例对象并不能调用

Object.getPrototypeOf()

作用是获取目标对象的原型
function F() {};
var obj = new F();
console.log(Object.getPrototypeOf(obj) === F.prototype);

其等同于求obj.__proto__ = obj.[[prototype]]的值
需要注意的是普通函数也是Function的实例对象,所以function f() {}; Object.getPrototypeOf(f); // Function.prototype

Object.setPrototypeOf()

作用是为目标对象设置原型

var sub = {a : 1};
var super = {b : 1};
Object.setPrototypeOf(sub, super);  //sub.__proto__ = super

Object.setPrototypeOf要实现的效果就是sub.__proto__ = super,也就是Object.getPrototypeOf(sub)等于 super,返回值是sub
模拟new的实现

function F() {
    this.a = 123;
};
var o = new F();
//等价于
//var o1 = Object.setPrototypeOf({}, F.prototype);  创建一个空对象并且以F.prototype为原型的实例对象
//F.call(o1);                                       并将this的属性以及方法给o1

Object.create()

作用与setPrototypeOf类似,创建一个空对象并以参数对象为原型的实例对象,第一个参数必须是对象或者null

var o = new Object();
//var o = Object.create({});
//var o = Object.create(Object.prototype);

看起来Object.prototype等同于空对象,我的理解是这边因为赋值都是

{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}

所以这三者等价
create的创建模拟如下:

function creat(obj) {
    function F() {};
    F.prototype = obj;   //prototype的作用就是将值放入o.__proto__中(o = new F())
    return new F();
}

因为{}与Object.prototype赋值给F.prototype值一样,所以结果一样
当参数为null时,返回的实例对象,是比空值还空的对象,不继承Object的原型
还可以填入第二个参数,参数为属性描述对象,并将其属性添加到实例对象中

var supe = {b : 2};
var obj = Object.create(supe, {
    a : {
        value : 123,
        writable : true,
        enumerable : true,
        configurable : true, 
    }

});
//obj
//{a: 123}
//a: 123
//    __proto__: 
//        b: 2                  //这边是prototype赋入的b
//        __proto__: Object

Object.assign()

Object.assign(target,sources...sources)
作用是将源对象的自身可遍历属性浅拷贝到目标对象中,并返回最终的目标对象
注意点是:

  1. 可遍历属性
  2. 自身(OwnProperty)属性
  3. 相同且可修改属性会覆盖,不可修改属性覆盖会报错
  4. string或者Symbol类型是可以被直接分配的 (Symbol还未接触,暂且放放)
var suber = Object.create({a : 1}, {
    a : {
        value : 0,
        writable : true,   //false时,target为suber时会报错
        enumerable : false,
        configurable : true,
    },
    b : {
        value : 1,
        writable : true,
        enumerable : true,
        configurable : true,
    },
    c : {
        value : "c",
        writable : true,
        enumerable : true,
        configurable : true,
    },
});
var suber1 = Object.create({t : 1}, {
    b : {
        value:2,
        writable : false,
        enumerable : true,
        configurable : true,
    }
});
var suber2 = Object.create({a : 1}, {
    b : {
        value : 3,
        writable : true,
        enumerable : true,
        configurable : true,
    }
});
console.log(Object.assign(suber, suber1,suber2));       //{b: 3, c: "c", a: 0}
//console.log(Object.assign({}, suber, suber1,suber2)); //{b: 3, c: "c"}

从代码中可看出:

  • 判断是否只读是以target对象的属性描述对象为基准,当target为{}时,b的所有enumerable为false,也能赋值上去
  • 属性描述对象并不会拷贝

只有原始类型为string才可以被直接分配的,(Symbol还未接触,暂且放放)

console.log(Object.assign({},"asd"));  //{0: "a", 1: "s", 2: "d"}

Object的实例方法

Object.prototype.isPrototypeOf()

isPrototypeOf作用判断目标对象是否为参数对象的原型o1.isPrototypeOf(o2)==> o1 === o2.__proto__ ? true : false
由这个全等符号也可以看出原型链就是对象之间的链接就是对象引用(地址)的赋值

in与for-in

in运算符返回一个布尔值,表示一个对象是否具有某个属性。它不区分该属性是对象自身的属性,还是继承的属性。
不管是否可以遍历
for-in:遍历对象所有可遍历属性。它不区分该属性是对象自身的属性,还是继承的属性。
那么我们要遍历对象所有属性,包括继承以及不可遍历的属性,
用getOwnPropertyNames加原型遍历实现

function getAllPropertyNames(target) {
    //var arr = [];
    var props = {};
    while(target) {
        Object.getOwnPropertyNames(target).forEach(function(p) {
            
                props[p] = true;
        });
        target = Object.getPrototypeOf(target);
        
    }
    
    return Object.getOwnPropertyNames(props);
}
var o = {a : 1};
console.log(getAllPropertyNames(o));

类似的用递归

function getAllPropertyNames(n) {
    var sup = Object.getPrototypeOf(n);
    if (sup == null) {
        return Object.getOwnPropertyNames(n);
    }
    return Object.getOwnPropertyNames(n).concat(getAllPropertyNames(sup));
}

Array.prototype.unique = function() {
    var obj = {};
    this.forEach(function (elem) {
        obj[elem] = true;
    });
    return Object.getOwnPropertyNames(obj);
}
console.log(getAllPropertyNames(Date).unique());

Infinity
293 声望9 粉丝

学前端中,只想激情优雅的写代码