资讯专栏INFORMATION COLUMN

JavaScript学习之Object(下)相关方法

amuqiao / 1222人阅读

摘要:它不区分该属性是对象自身的属性,还是继承的属性。那么我们要遍历对象所有属性,包括继承以及不可遍历的属性,用加原型遍历实现类似的用递归

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)
作用是将源对象的自身可遍历属性浅拷贝到目标对象中,并返回最终的目标对象
注意点是:

可遍历属性

自身(OwnProperty)属性

相同且可修改属性会覆盖,不可修改属性覆盖会报错

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());

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/98198.html

相关文章

  • JavaScript习之Object()new命令

    摘要:命令作用作用是执行构造函数,返回实例对象上面例子是自定义一个构造函数,其最大的特点就是首字母大写,用执行构造函数其中,在的执行下,代表了实例化后的对象,这个也就有属性注意点如果不用执行构造函数,那么指向的是全局有两种方式可以避免内部定义严格 new命令 new作用 作用是执行构造函数,返回实例对象 function F() { this.name = object } var ...

    Salamander 评论0 收藏0
  • JavaScript习之对象原型及继承

    摘要:原型要掌握这三者之间的关系,通过代码例子记录一下自身属性的这里就是通过代码看一下做了什么默认情况下,将的所有属性包括继承的赋值给有什么东西呢自己的原型链,添加一个属性,用来指明对象的谁构造的自身全部属性,这边构建一个空对象原型,所以没有自有 原型 要掌握这三者之间的关系prototype,constructor,__proto__通过代码例子记录一下 function F() { ...

    妤锋シ 评论0 收藏0
  • JavaScript习之JSON对象

    摘要:原始类型的值只有四种字符串数值必须以十进制表示布尔值和不能使用和。字符串必须使用双引号表示,不能使用单引号。数组或对象最后一个成员的后面,不能加逗号。 JSON对象 补充记录一下,有些方法很需要熟练记忆的 JSON对象的规定 JSON对象对值有严格的规定 复合类型的值只能是数组或对象,不能是函数、正则表达式对象、日期对象。原始类型的值只有四种:字符串、数值(必须以十进制表示)、布尔值和...

    banana_pi 评论0 收藏0
  • Javascript习之继承

    摘要:继承是面向对象编程语言中的一个重要的概念,继承可以使得子类具有父类的属性和方法或者重新定义追加属性和方法等。但是在中没有类的概念,是基于原型的语言,所以这就意味着对象可以直接从其他对象继承。 继承是面向对象编程语言中的一个重要的概念,继承可以使得子类具有父类的属性和方法或者重新定义、追加属性和方法等。但是在Javascript中没有类的概念,是基于原型的语言,所以这就意味着对象可以直接...

    CHENGKANG 评论0 收藏0
  • javaScript习之隐式转换

    摘要:搬家篇三开胃菜因为大于等于的比较,不是相等的比较,所以值得注意的操作符一元操作符通过进行转换其中包括号运算符,号运算符,都是经转换逻辑运算符等价于将操作数进行布尔值类型转换位操作当一边操作数为时,可等价于操作数为由以下变化可以证得加号运算 搬家篇三 开胃菜 [] == ![] //true ==> == false 123 ^ [] ...

    peixn 评论0 收藏0

发表评论

0条评论

amuqiao

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<