JS对象

什么是对象

  • js中,任何值都可以转换为对象,以对象的方式进行使用,如数字对象、布尔值对象、字符串对象、类型对象、函数对象、数组对象等,它们都继承 Object类型对象,拥有共同的基本属性和方法。
  • 此外, JavaScript也允许自定义对象,从狭义的概念来分析,对象(Object)是最基本的数据类型,是复合型的结构、引用型的数据,它是无序数据集合,对象中每个成员被称为属性。

定义对象

构造函数

  • 使用new运算符调用构造函数,可以构造一个实例对象,具体用法如下var objectName = new functionName (args)
  • 参数说明如下
    • objectName:返回的实例对象
    • functionName:构造函数,与普通函数基本相同
    • args:实例对象初始化配置参数列表
var num1 = new Number(111);
console.log(num1);

var obj = new Object({
    name:1
});
console.log(obj);

对象直接量

  • 使用直接量可以快速定义对象,也是最高效、最简便的方法。var objectName = {属性名1:属性值1,属性名n:属性值}
  • 在对象直接量中,属性名与属性值之间通过冒号进行分隔,属性值可以是任意类型的数据,属性名可以是 JavaScript标识符,或者是字符串型表达式,属性与属性之间通过逗号进行分隔,最后一个属性末尾不需要逗号。
  • 如果属性值是对象,可以设计嵌套结构的对象
  • 如果不包含任何属性,则可以定义一个空对象
var obj1 = {
    name:"lily",
    "sex":"女",
    score:[100,90,80,12,35,34],
    fri:{
        fir1:"xiaowang",
        fir2:"xiaoli",
        fir3:{
            sis1:"dahua",
            sis2:"xiaohua",
            sis3:["zhangdama","zhangxiaoma","zhangma"]
        }
    }
}
console.log(obj1.sex);

使用 Object create

  • Object.create是 ECMAScript5新增的一个静态方法,用来定义一个实例对象。
  • 该方法可以指定对象的原型和对象特性。具体用法如下object.create (prototype, descriptors)
    • prototype:必须参数,指定原型对象,可以为null
    • descriptors可选参数,包含一个或多个属性描述符的 JavaScript对象。属性描述符包含数据特性和访问器特性,其中数据特性说明如下
      • value:指定属性值
      • writable:默认为 false,设置属性值是否可写
      • enumerable:默认为 false,设置属性是否可枚举( for/in)
      • onfigurable:默认为flse,设置是否可修改属性特性和删除属性
      • 访问器特性包含两个方法,简单说明如下set():设置属性值,get():返回属性值
//Object.create方法
var obj = {};
console.log(obj);

var obj2 = Object.create(obj1);
console.log(obj2);//空对象  但是继承了obj1
console.log(obj2.name);//自己没有没关系  他爹有

//创建一个干净的对象
var obj3 = Object.create(null);
console.log(obj3);

//创建一个对象
var obj4 = Object.create(null,{
    name:{
        value:"xiaowang",
        writable:true,
        enumerable:true,
    },
    sex:{
        value:"nv"
    }
})
console.log(obj4);
console.log(obj4.name);
obj4.name = "laowang";
console.log(obj4);

for(i in obj4){
    console.log(i);
}


//访问器属性
var obj5 = Object.create(null,{
    a:{
        value:"hello",
        writable:true
    },
    b:{
        get:function () {
            return this.a+" world"
        },
        set:function (i) {
            this.a = i + "我拖堂了";
        }
    }
})
console.log(obj5);
console.log(obj5.b);//当调用一个属性的时候,会访问他的访问器属性的get,get方法的返回值就是b的值
obj5.b = "hahaha";//当设置属性的时候,会调用访问器的set方法,设置的值就是方法的参数
console.log(obj5);

对象属性的操作

属性也称为名值对,包括属性名和属性值。一个对象中不能存在两个同名的属性。属性值可以是任意类型的数据

定义属性

直接量定义

在对象直接量中,属性名与属性值之间通过冒号分隔,冒号左侧是属性名,右侧是属性值,名值对(属性)之间通过逗号分隔。

//使用直接量定义
var obj1 = {
    name:"laowang",
    sex:"男"
};
var obj2 = new Object({
    name:"xiaowang",
    sex:"nv"
})
var obj3 = Object.create(null,{
    name:{
        value:"dawang",
        writable:true
    },
    sex:{
        value:"nan"
    }
})

点语法定义

//点语法定义:
var obj4 = {
    name:"xiaozhang"
}
obj4.sex = "nan";
console.log(obj4);

var obj5 = new Object({
    name:"xiaowang",
    sex:"nv"
})
obj5.age = 20;
console.log(obj5);

var obj6 = Object.create(null,{
    name:{
        value:"dazhang",
        writable:true,
    }
})
obj6.age = 10;//也可以直接对 create创建的对象设置属性,但是无法选择属性的特性,默认可以被修改,可以被枚举
console.log(obj6);
obj6.age = 20;
console.log(obj6);
for(var i in obj6){
    console.log(i);
}

中括号语法

var obj7 = {
    name:"xiaowang"
}
var  a= "sex"
obj7[a] = "nv";
obj7["sex"] = "nv";
console.log(obj7);


function getMess(obj,pro) {
    return obj[pro]
}
var myself = {name:"huahua",sex:"nan",age:"19"};
console.log(getMess(myself, "sex"));

Object.defineProperty

使用 Object.defineProperty函数可以为对象添加属性,或者修改现有属性。如果指定的属性名在对象中不存在,则执行添加操作:如果在对象中存在同名属性,则执行修改操作

// Object.defineProperty(obj,pro,{})
var obj8 = {
    name:"xiaoli"
}
Object.defineProperty(obj8,"sex",{
    value:"nv",
});
Object.defineProperty(obj8,"name",{
    //如果修改原有的name属性值,它可以被修改和枚举
    value:"dali",
});
console.log(obj8);
for(var i in obj8){
    console.log(i);
}

使用Object.defineProperties

  • 可以一次定义多个属性
  • Object.defineProperties(object,description)
    • object:对其添加或修改属性的对象,可以是本地对象或DOM对象
    • description:包含一个或多个描述符对象,每个描述符对象描述一个数据属性或访问器属性
var obj9 = {
    like:"miantiao"
}
Object.defineProperties(obj9,{
    color:{
        value:"yellow",
        enumerable:true
    },
    length:{
        value:"10m",
    }
})
console.log(obj9);

读属性

使用点语法

使用点语法可以快速读写对象属性,点语法左侧是引用对象的变量,右侧是属性名。

var obj1 = {
    name:"xiaowang",
    like:"唱跳rap篮球",
    time:"两年半"
}
console.log(obj1.name)

使用中括号语法

  • 从结构上分析,对象与数组相似,因此可以使用中括号来读写对象属性
  • 在中括号语法中,必须以字符串形式指定属性名,不能使用标识符。
  • 中括号内可以使用字符串,也可以使用字符型表达式,即只要表达式的值为字符串即可
// 案例 for in 遍历重写
var obj1 = {
    name:"xiaowang",
    like:"唱跳rap篮球",
    time:"两年半"
}

for(var item in obj1){
    console.log(item);
    obj1[item] = obj1[item] + "@";
}
console.log(obj1);

Object.getOwnPropertyNames

  • 使用 Object.getOwnPropertyNames函数能够返回指定对象私有属性的名称。
  • 私有属性是指用户在本地定义的属性,而不是继承的原型属性。
var obj1 = {
    name:"xiaowang",
    like:"唱跳rap篮球",
    time:"两年半"
}
console.log(Object.getOwnPropertyNames(obj1));//["name","like","time"]

使用Object.keys

使用 Object.keys()函数仅能获取可枚举的私有属性名称,返回值是一个数组,其中包含对象的可枚举属性名称

Object.getOwnPropertyDescriptor()

  • 能够获取对象属性的描述符
  • Object.getOwnPropertyDescriptor(object,propertyname)
  • 参数object表示指定的对象,propertyname表示属性的名称,返回值为属性的描述符对象
//对 create方法创建的对象 进行属性设置
var obj2 = Object.create(null,{
    name:{
        value:"新宝岛",
        enumerable:true
    },
    time:{
        value:"5min",
        enumerable:true
    },
    like:{
        value:"rap"
    }

})
console.log(Object.getOwnPropertyNames(obj2));//["name","like","time"]
console.log(Object.keys(obj2));//["name","time"]

console.log(Object.getOwnPropertyDescriptor(obj1, "like"));//{value: "唱跳rap篮球@", writable: true, enumerable: true, configurable: true}
console.log(Object.getOwnPropertyDescriptor(obj2, "time"));//{value: "5min", writable: false, enumerable: true, configurable: false}

删除属性

使用 delete运算符可以删除对象的属性 当删除对象属性之后,不是将该属性值设置为 undefined,而是从对象中彻底清除属性

var obj = {
    name:"laowang",
    sex:"nan",
    like:undefined
}
console.log(obj.like);//可以设置一个属性值为undefined
console.log(Object.getOwnPropertyNames(obj));//设置为undefined值的属性名 仍然可以获取到

delete obj.sex;//删除一个属性
console.log(obj);
console.log(Object.getOwnPropertyNames(obj));//当一个属性被删除的话,就枚举不到他的这个属性名了

控制对象状态

  • Object.preventExtensions():阻止为对象添加新的属性
  • Object.seal():阻止为对象添加新的属性,同时也无法删除旧属性。等价于把属性描述对象的configurable属性设为false。注意,该方法不影响修改某个属性的值
  • Object.freeze():阻止为一个对象添加新属性、删除旧属性、修改属性值 同时提供3个对应的辅助检查函数
  • Object.isExtensible():检查一个对象是否允许添加新的属性
  • Object.isSealed():检查一个对象是否使用了 Object.seal方法
  • Object.isFrozen():检查一个对象是否使用了 Object.freeze方法
// 1.Object.preventExtensions():
var obj = {
    name:"xiaoxinxin",
    width:"200",
    height:"300"
}
console.log(obj);
obj.color = "red";//设置新属性
console.log(obj);
console.log(Object.isExtensible(obj));
Object.preventExtensions(obj);//阻止设置新属性
console.log(Object.isExtensible(obj));
obj.bg = "green";
console.log(obj);//阻止以后 无法设置新属性


// 2.Object.seal():
var obj2 = {
    name:"dadudu",
    width:"200",
    height:"300"
}
console.log(obj2);
delete obj2.width;//删除一个旧属性
console.log(obj2);
console.log(Object.isSealed(obj2));
Object.seal(obj2)//阻止添加新属性 和删除旧属性
console.log(Object.isSealed(obj2));
delete obj2.height;
console.log(obj2);


// 3.Object.freeze()
var obj3 = {
    name:"xiaowangba",
    width:"200",
    height:"300"
}
console.log(obj3);
obj3.width = "1000";//修改旧属性
console.log(obj3);
console.log(Object.isFrozen(obj3));
Object.freeze(obj3);
console.log(Object.isFrozen(obj3));
obj3.height = "800";
console.log(obj3);

对象的遍历

  • for in 循环 专门用来遍历对象
  • for in中定义的变量 代表着 对象的键名
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>对象的遍历</title>
</head>
<body>
<script>
    var person = {
        headTeacher:{
            name:"小宁姐",
            sex:"20",
            age:"nv",
            method:"班主任"
        },
        jobTeacher:{
            name:"丽丽",
            sex:"22",
            age:"nv",
            method:"就业"
        },
        bossTeacher:{
            name:"老谭",
            sex:"50",
            age:"男",
            method:"校长"
        }
    }
    console.log(person.length);//undefined 对象是没有length属性的

    function teacherMessage(obj) {
        alert("我的名字是"+obj.name);
        alert("我的年龄是"+obj.age);
        alert("我的性别是"+obj.sex);
        alert("我的作用是"+obj.method);
    }

    // for in 循环  专门用来遍历对象
    // for in中定义的变量 代表着 对象的键名
    for(var i in person){
        // console.log(i);
        teacherMessage(person[i]);
    }
</script>
</body>
</html>

基本类型和引用类型

概念

  • 数据类型中 分为5种简单的数据类型和1种复杂的数据类型,他们分别对应着基本类型值和引用类型值
  • 基本类型值:null undefined string number boolean
  • 引用类型值:object(正则、数组、对象、函数。。。。。)
  • 什么这么分类:是按照这两种值存储的方式不同来分类的

基本类型值

  • 基本类型值:null undefined string number boolean
  • 基本类型值都是按值访问 直接操作保存在变量中的实际值
  • 基本类型值都是存储在栈区中,我们可以直接通过变量名访问实际值
var num1 = 10;//在栈区开启一个空间  栈区的名是变量名  栈区的值是 这个变量所对应的的值
var num2 = num1; //重新开辟一个区域保存num2的值,获取num1的值 并赋值给num2
num1 = 30;//改变栈区num1的值为30   但是不会影响num2
console.log(num1,num2);//30 10
  • 基本类型值的特点:
    1. 基本类型的值是不可变的
    2. 我们不能给基本类型值添加属性和方法 就算添加也是获取不到的
    3. 基本类型的比较是值的比较
    4. 基本类型的变量是存放在栈区的(栈区指内存里的栈内存),栈区包括了变量的标识符和变量的值
// 1、基本类型的值是不可变的
/*数组添加一个值,还是原来的数组。
  如果基本类型值发生改变,那么久不再是原来的值,而是重新赋值了。
  所以我们不能改变基本类型的值,否则就是直接换了值
*/

// 2、我们不能给基本类型值添加属性和方法  就算添加也是获取不到的
var str1 = "abc";
str1.eat = "apple";//给基本类型 扩展了一个属性  eat
str1.say = function () {//给基本类型值 扩展一个方法
    alert("你说话呀");
}
console.log(str1.eat);//undefined
str1.say();//str1.say is not a function


// 3、基本类型的比较是值的比较
var num1 = 5;
var num2 = null;
console.log(num1 < num2);//基本类型值的比较 都是拿出变量所对应的值来进行比较的  先取出来再转换类型比较

// 4、基本类型的变量是存放在栈区的(栈区指内存里的栈内存),栈区包括了变量的标识符和变量的值

引用类型值

  • 引用类型值再栈区储存的是 标识符(变量名)和引用地址 在堆区储存的是对象的值
  • 当我们访问某一个对象的时候,要先访问到栈区的地址 然后引用到堆区的值
var obj1 = {
    name:"lily"
}//声明一个对象,然后值保存在堆区  变量和引用地址保存在栈区
var obj2 = obj1;//赋值都是 栈区引用地址的赋值  把obj1的地址赋值给了obj2
obj1.name = "lucy";//改变了obj1 堆区对象值的内容
console.log(obj1,obj2);//obj1 和obj2 引用地址是一样的 所以指向的是同一个对象
  • 引用类型值特点:
    1. 引用类型的值是可变的,我们可以为引用类型添加属性和方法
    2. 引用类型的值是同时保存在栈内存和堆内存中的对象
    3. 引用类型的比较是引用的比较
// 1、引用类型的值是可变的,我们可以为引用类型添加属性和方法
var arr1 = [1,2,3];
arr1.say = function () {
    alert("你好呀");
}
arr1.say();

// 2、引用类型的值是同时保存在栈内存和堆内存中的对象

//3、引用类型的比较是引用的比较
var obj1 = {};
var obj2 = {};
console.log(({} == {}));//false  两个对象虽然是空对象  然后再栈区的地址不一样  而比较是栈区的引用地址的比较  所以返回false
posted @ 2023-01-12 21:52  z_bky  阅读(38)  评论(0)    收藏  举报