前端学习(四十五) JavaScript-对象(javaScript)

对象是JS的基本数据类型,对象是一种复合值,它将很多值聚合在一起,可以通过它们的键值(属性名)来访问他们的这些属性值

对象的创建

  • var obj=new Object();
  • var obj={};
  • var obj=Object.create(Object.prototype)   //es5中的方法
var a={
    tee:"asd",
    glass:"aaaa",
    clockIn:function () {
        alert("AM 9:30")
    },
    clockOut:function () {
        alert("PM 9:30")
    }
};

另外可以定义新属性:

a.pants="asdfa";
a['kaddd']="asdff";

这两种都可以输出是一样的,第一个是新增了一个属性名为pants,属性值为asdfa的属性,第二个是新增了一个属性名为kaddd,属性值为asdff的属性;

还有是在es5中有两个方法,十分重要,用于对 对象 其中的属性进行定义或者修改,一个是Object.defineProperty(),另一个是Object.defineProperties(),另外在es5中增加了属性描述符,通过属性描述符可以更加细腻的控制属性的不同操作,属性描述符分为两种类型:数据描述符存取描述符

数据描述符:是一个可写或者不可写值的属性。

存取描述符:是由一对getter和setter函数功能来描述属性。

描述符必须是两者之一,但是不能共存。(https://blog.csdn.net/qq_17335153/article/details/52584727)

属性描述符 数据描述符 存取描述符 描述
configurable Yes Yes

当且仅当configurable为true时,属性描述符才可以被修改(属性描述符的修改

得使用defineProperty()和defineProperties()方法),另外该属性也可以从对象上

被删除默认值为false

enumerable Yes Yes

当且仅当enumerable为true时,该属性才可以被枚举(枚举属性代表可以被for...in查询到

查不到的代表不具备枚举属性),默认为false

value Yes No value该属性对应的值,默认为undefined
writable Yes No 当且仅当writable为true时,value才可以被赋值运算符改变,默认为false
get No Yes

给属性提供get方法,如果没有getter则为undefined,该方法返回值被用作属性值这个

理解成是为了获取返回值默认为undefined

set No Yes

给属性提供setter方法,如果没有setter则为undefined,该方法将接受唯一参数,并

将该参数的新值分配给该属性(这个是为了设置属性,并不需要返

回值),默认为undefined

 

Object.defineProperty(obj,prop,descriptor):这个方法的主要功能是对 对象的属性和属性值进行定义和修改,但这个方法添加的只能是一个属性和属性值

obj:目标对象,要对这个对象新增或修改属性

prop:要新增或者修改属性的名字

descriptor:属性描述符

,举个例子:

Object.defineProperty(a,"name",{
    set:function (value) {
        switch (value){
            case 'nike':
                alert("nike");
                break;
            case "ven":
                alert("ven");
                break;
            default:
                alert("这个比较奇葩")
                break;

        }
    }
})

解释:给a这个对象,添加或修改属性名为name的属性值,具体修改后的属性值为function里的方法计算出来的

Object.defineProperties(obj,descriptor)

defineProperties是defineProperty的复数,显然可见是可以给对象进行多个属性的添加和修改

obj:目标对象,要对这个对象做一些操作

descriptor:属性描述符

var xm={}
Object.defineProperties(xm,{
    "glass":{   //属性名
        value:"joy",    //属性值
        writable:true,  //允许属性值“joy”被写入修改
        configurable:false,//不允许delete xm.galss,不允许defineProperty()修改属性描述符
        enumerable:false//不允许被for..in查询到

    },
    "arm":{ //属性名
        configurable:true,  //允许删除,允许使用defineProperty()修改属性描述符
        enumerable:true,    //允许被搜索到
        set:function (value) {    //给这个属性设置一个函数,注意,调用对象的函数的方法是xm.xarm(),有括号的,代表方法,不是xm.xarm,没有括号意思是打印值
            return value;
        }
    },
    "xarm":{    //属性名
        configurable:false,
        enumerable:false,
        value:function () {   //属性值,这边属性值是一个函数,注意,调用对象的函数的方法是xm.xarm(),有括号的,代表方法,不是xm.xarm,没有括号意思是打印值
            alert(1);
        }
    }
})

Object.create(prototype,descriptor)

创建一个具有指定原型,可选择性包含指定属性的对象,最终返回的是新创建的对象

prototype:指新创建对象的原型对象

descriptor:添加到新创建对象的属性

var pol=Object.create(Object.prototype,{
    glass:{ //属性名
        value:"joy",    //属性值
        writable:true,  //可写入
        configurable:false, //允许被defineProerty()修改,这个属性允许被delete删除,这个例子就是允许被delete pol.glass
        enumerable:false    //允许被for...in搜索到
    }
})
console.log(pol)

属性的访问

var a={

name:"toy",

sex:"男",

asd:function(a){}

}

a.name;   //访问name属性,输出toy

a.asd(a);   //访问asd方法,并传参数a

a['name']  //访问name属性,输出toy

a['asd']   //?这个还要查一查

属性的设置

var pokx={
    xaaa:"asd"
};
Object.defineProperties(pokx,{
    name:{  //属性名
        value:"joy",    //属性值
        configurable:true,  //可删除可修改属性描述符
        writable:false  //可写入修改
    }
})
console.log(pokx)

pokx.xaaa;   //输出asd

pokx.xaaa="qwe";   //输出qwe,可修改

pokx.name;  //输出joy

pokx.name="ree";  //输出ree,因为writable为false,不允许写入

属性的删除

var pokx={
    xaaa:"asd"
};
Object.defineProperties(pokx,{
    name:{  //属性名
        value:"joy",    //属性值
        configurable:false,  //可删除可修改属性描述符
        writable:false  //可写入修改
    }
})
console.log(pokx)

delete pokx.xaaa;  //输出true,删除成功

delete pokx.name;   //输出false,删除失败,因为修改新定义的属性name的configurable设置成了false,不允许修改或删除

属性的检测

  • for...in:运算符,通过for...in检测对象上包括原型链上的所有具有枚举属性的对象
var obj={
    xaaa:"asd"
};
Object.defineProperties(obj,{
    name:{  //属性名
        value:"joy",    //属性值
        configurable:false,  //可删除可修改属性描述符
        writable:false, //可写入修改
        enumerable:true
    },
    galss:{
        value:function (a) {
            return a
        },
        enumerable:true
    },
    shit:{
        value:"ul",
        enumerable:false
    }
})
Object.prototype.ola=function () {
    
};
for (var a in obj){
    console.log(a); //这里输出把整个对象上添加的ola也输出了
}
  • hasOwnProperty():检测对象上的自由属性,如果是自有属性,则返回true,如果没有则返回false
for (var a in obj){
    if(obj.hasOwnProperty(a)==true){  //也可以直接判断obj.hasOwnProperty(a)
        console.log(a); //这里输出就不会出出ola属性了
    }
}
  • propertyIsEnumerable():检测自有且可枚举的属性,是hasOwnProperty()方法的进一步加强

枚举属性

  • for...in,下例中用for..in显示了所有的枚举属性,如果enumerable设置了false,那么属性就不会被for...in到
  • Object.key(obj):是es5中的一个方法,只会将对象自有的属性名以数组的形式返回,这个方法就不必担心有没有原型链上的对象,示例如下
var obj={
    xaaa:"asd"
};
Object.defineProperties(obj,{
    name:{  //属性名
        value:"joy",    //属性值
        configurable:false,  //可删除可修改属性描述符
        writable:false, //可写入修改
        enumerable:true
    },
    galss:{
        value:function (a) {
            return a
        },
        enumerable:true
    },
    shit:{
        value:"ul",
        enumerable:false
    }
})
Object.prototype.ola=function () {
    
};
var aox=Object.keys(obj);
console.log(aox);

这边最终会输出:[‘xaaa’,‘name’,‘galss’],其中shit因为enumerable设置了false,无法被枚举,而整个对象上的ola则不是obj的自有属性。

属性复制

Object.assign(terget,...sources)

terget:目标对象

...sources:一个或多个的源对象

  • 将所有 可枚举的属性的值 从 一个或多个源对象 上 复制 目标对象,然后将返回新生成的目标对象
  • 如果目标对象中的属性具有相同的键,则属性将被源中的属性覆盖后来的源的属性将类似的覆盖早先的属性
var aa={
    name:"joy",
    glass:"sk",
    shit:"shit"
}
var ab={
    name:"pol",
    shit:"sk"
}
var ac={
    glass:"oi"
}
var ad=Object.assign(ac,aa,ab)
console.log(ad)

最终输出的ad:{name:"pol",glass:"sk",shit:"sk"},个人觉得,如果目标对是空对象,那么将源对象上的复制并覆盖过去可以说得通,如果是多个对象,就像上例中的那样,感觉其实更像是合并

对象的原型方法

Object.prototype.constructor;

通过这个方法返回目标对象的构造函数

var aoc=obj.constructor
console.log(aoc);

输出:object

Object.prototype.toString()

经常用来检测对象类型

console.log(aoc.call(new Object))   //[object Object]
console.log(aoc.call(new Date));    //[obejct Date]
console.log(aoc.call(new String))   //[object String]

Obejct.prototype.valueof()

返回对象的原始值,具体示例如下:

var obj={
    xaaa:"asd"
};
Object.defineProperties(obj,{
    name:{  //属性名
        value:"joy",    //属性值
        configurable:false,  //可删除可修改属性描述符
        writable:false, //可写入修改
        enumerable:true
    },
    galss:{
        value:function (a) {
            return a
        },
        enumerable:true
    },
    shit:{
        value:"ul",
        enumerable:false
    }
})

输出:{xaaa:"asd",name:"joy",galss:f(a),shit:'ul'}

猜你喜欢

转载自blog.csdn.net/zy21131437/article/details/81142923