欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

荐 js中的对象

程序员文章站 2022-04-19 13:31:10
js中的对象除了五种基本数据类型外还有一个引用数据类型:Object 对象(以后我们看到的值,只要不是五种基本数据类型的,全都是对象)如果使用基本数据类型的数据,我们所创建的变量都是独立的,不能成为一个整体,例如:var name = "孙悟空";var gender = "男";var age = "18";//这三个数据毫无关联,互相独立Js中的变量都是保存到栈内存中的基本数据类型的值直接在栈内存中存储,值与值之间是独立存在的,修改一个变量不会影响到其他变量[外链图片转存失败,...

js中的对象

除了五种基本数据类型外还有一个引用数据类型:Object 对象(以后我们看到的值,只要不是五种基本数据类型的,全都是对象)

如果使用基本数据类型的数据,我们所创建的变量都是独立的,不能成为一个整体,例如:

var name = "孙悟空";
var gender = "男";
var age = "18";//这三个数据毫无关联,互相独立
  • Js中的变量都是保存到栈内存中的

    基本数据类型的值直接在栈内存中存储,值与值之间是独立存在的,修改一个变量不会影响到其他变量

荐
                                                        js中的对象

对象是保存在堆内存中,每创建一个新的对象,就会在堆内存中开辟出一个新的空间,而变量保存的是对象的内存地址(对象的引用),如果两个变量保存的是同一个对象引用,当一个对象通过一个变量修改属性时,另一个也会受影响

荐
                                                        js中的对象

当给其中一个对象赋值时,会切断与之前地址的连接

荐
                                                        js中的对象
当比较两个两个基本数据类型时,就是比较的值,而比较两个引用数据类型时,是比较对象的内存地址,如果两个对象的值是一模一样的,但地址不同,也会返回false

荐
                                                        js中的对象

  • 对象属于一种复合的数据类型,在对象中可以保存多个不同类型的属性

  • 对象的分类

    • 1.内建对象

      由ES标准中定义的对象,在仍何的ES实现中都可以使用,如:Math String Number Boolean…

    • 2.宿主对象

      由JS的运行环境提供的对象,目前主要是指由浏览器提供的对象,如:BOM DOM

    • 3.自定义对象

      由开发人员自己创建的对象

ps:对象就像一个塑料袋!!

内建对象
数组(Array)
  • 数组也是一个对象

  • 他和我们普通的对象功能相似,也是用来存储一些值的

  • 不同的是普通对象是使用字符串作为属性名的,而数组是使用数字作为索引来操作对象

  • 索引:

    从零开始的整数就是索引

  • 数组的存储性能比普通对象要好,在开发中我们经常使用数组来储存一些数据

创建数组对象

**语法:**数组[索引] = 值

var arr = new Array();
console.log(arr);//输出""  空的,因为里面没有元素
arr[0] = 10;
arr[1] = 33;
console.log(arr);//输出10,33

使用字面量创建数组

语法:[]

使用字面量创建数组时,可以在创建时就指定数组中的元素

使用构造函数创建数组时,也可以同时添加元素,将要添加的元素作为构造函数参数传递,元素之间用,隔开

当只传一个数时,字面量传的是一个元素而构造函数传的是数组的元素数量

var arr = new Array();
var arr = [];
console.log(arr);//返回值为空(没有设置元素)

var arr = [1,2,3,4,10];
console.log(arr[4]);//返回值为10 

var arr2 = new Array(10,20,30);
console.log(arr2);//返回值为10,220,30(与上面的方法效果一样)

引用数组对象

**语法:**数组[索引]

如果读取不存在的索引,不会报错而是返回undefined

var arr = new Array();
arr[0] = 10;
arr[1] = 33;
console.log(arr[1]);//输出33

获取对象长度

可以使用length属性来获取数组的长度

对于连续的数组使用length可以获取到数组的长度(元素个数)

对于非连续的数组,使用length会获取到数组的最大索引+1

尽量不要创建非连续的数组,占空间

**语法:**数组.length

var arr = new Array();
arr[0] = 10;
arr[1] = 33;
console.log(arr.length);//输出2
arr[10] = 50;
console.log(arr.length);//输出11
console.log(arr)//[ 10, 33, <8 empty items(8个空的项目)>, 50 ]

修改length

如果修改的length大于原长度,则多余部分会空出来

如果修改的length小于原长度,则多出部分会被删除

var arr = new Array();
arr[0] = 10;
arr[1] = 11;
arr[2] = 22;
arr[3] = 33;
arr.length = 10;
console.log(arr.length);//输出10
console.log(arr)//输出[ 10, 11, 22, 33, <6 empty items> ]
arr.length = 2;
console.log(arr.length);//输出2
console.log(arr)//输出10,11

向最后的一个位置添加元素

var arr = new Array();
arr[0] = 10;
arr[1] = 11;
arr[2] = 22;
arr[3] = 33;
console.log(arr.length);//输出4
console.log(arr)//输出10,11,22,33
arr[arr.length] = 44;
console.log(arr.length);//输出5
console.log(arr)//输出10,11,22,33,44
  • 数组中的元素可以是任意的数据类型
var arr = new Array();
arr = ["hello",true,null,undefined];
console.log(arr)//输出hello,1,true, ,

也可以是对象

var obj = {name:"孙悟空"};
arr[arr.length] = obj;
console.log(arr[5].name);//输出孙悟空

也可以是个函数

var arr = new Array();
arr = [function(){alert(1)},function(){alert(2)}];
console.log(arr);//输出function(){alert(1)},function(){alert(2)}
arr[0]();//弹出1

数组中也可以放数组,如下这种数组叫二维数组

var arr = new Array();
arr = [[1,2,3],[4,5,6],[7,8,9]];
console.log(arr[0]);//输出1,2,3

push()

  • 该方法可以向数组的末尾添加一个或多个元素,并返回数组的新的长度
  • 可以将要添加的元素作为方法的参数传递,这样这些元素将会自动添加到数组的末尾
  • 该方法会将数组的新长度作为返回值返回
var arr = new Array();
var arr = ["孙悟空","猪八戒","沙和尚"];
arr.push("唐僧");
console.log(arr);//输出孙悟空,猪八戒,沙和尚,唐僧
arr.push("蜘蛛精","白骨精");
console.log(arr);//输出孙悟空,猪八戒,沙和尚,唐僧,蜘蛛精,白骨精
var arr = new Array();
var arr = ["孙悟空","猪八戒","沙和尚"];
var result = arr.push("蜘蛛精","白骨精","唐僧");
console.log(arr);//输出孙悟空,猪八戒,沙和尚,唐僧,蜘蛛精,白骨精
console.log(result);//输出  6

unshift()

  • 向数组开头添加一个或多个元素,并返回新的数组长度。
  • 像前面插入元素以后,其他元素会依次往后推
var arr = new Array();
var arr = ["孙悟空","猪八戒","沙和尚"];
var result = arr.push("蜘蛛精","白骨精","唐僧");
console.log(arr);
arr.unshift("牛魔王","二郎神");
console.log(arr);//输出  牛魔王,孙悟空,猪八戒,沙和尚,唐僧,蜘蛛精,白骨精

pop() shift()

  • pop(); 删除数组最后一个元素,并返回元素的值
  • shift();删除数组第一个元素,并返回元素的值

数组的遍历

一般是使用for循环来遍历数组

var arr = new Array();
var arr = ["孙悟空","猪八戒","沙和尚"];
var result = arr.push("蜘蛛精","白骨精","唐僧");
for(var i = 0 ; i < arr.length ; i++){
    console.log(arr[i]);//输出孙悟空,猪八戒,沙和尚,唐僧,蜘蛛精,白骨精
}

js中还提供了了一个方法,用来遍历数组

forEach()

  • 这个方法只支持ie8以上的浏览器

  • forEach() 方法需要一个函数作为参数

  • 像这种函数,由我们创建但是不由我们调用的,我们称为回调函数

  • 数组中有几个元素函数就会执行几次,每次执行时,浏览器会将遍历到的元素以实参的行书传递进来

  • 浏览器会在回调函数中传递三个参数

    第一个参数:当前正在遍历的函数

    第二个参数:当前正在遍历的元素的索引

    第三个参数:正在遍历的数组

var arr = new Array();
var arr = ["孙悟空","猪八戒","沙和尚","蜘蛛精","白骨精","唐僧"];
arr.forEach(function fun(a , b , c){   
    console.log(a);//输出 孙悟空 猪八戒 沙和尚 蜘蛛精 白骨精 唐僧
    console.log(b);//输出 0 1 2 3 4 5
    console.log(c);//输出[ '孙悟空', '猪八戒', '沙和尚', '蜘蛛精', '白骨精', '唐僧' ]
                      //[ '孙悟空', '猪八戒', '沙和尚', '蜘蛛精', '白骨精', '唐僧' ]
                      //[ '孙悟空', '猪八戒', '沙和尚', '蜘蛛精', '白骨精', '唐僧' ]
                      //[ '孙悟空', '猪八戒', '沙和尚', '蜘蛛精', '白骨精', '唐僧' ]
                      //[ '孙悟空', '猪八戒', '沙和尚', '蜘蛛精', '白骨精', '唐僧' ]
                      //[ '孙悟空', '猪八戒', '沙和尚', '蜘蛛精', '白骨精', '唐僧' ]
});

slice()

  • 可以用来从数组提取指定元素

  • 该方法不会改变元素数组,而是将截取到的元素封装到一个新数组中返回

  • 参数:slice(第一个参数,第二个参数)

    • 第一个参数:截取开始的位置索引(必须写)

    • 第二个参数:截取结束的位置索引(可省略,省略后会截取开始往后的所有元素)

    • 索引可以传递一个负值,如果传递一个负值则从后往前计算-1倒数第一个-2倒数第二个

    var arr = new Array();
    var arr = ["孙悟空","猪八戒","沙和尚","蜘蛛精","白骨精","唐僧"];
    console.log(arr.slice(0,2));//输出'孙悟空', '猪八戒'
    console.log(arr.slice(2));//输出'沙和尚', '蜘蛛精', '白骨精', '唐僧'
    console.log(arr.slice(-2));//输出'白骨精', '唐僧'
    

splice()

  • 可以删除或修改、添加数组中的指定元素

  • 使用splice会影响到原数组,会将指定元素从原数组中删除,并将被删元素作为返回值

  • 参数 splice(第一个参数,第二个参数)

    • 第一个参数(必写): 开始删除的位置索引
    • 第二个参数(必写): 表示删除的数量
    • 第三个及以后参数(可不写):可以传递一些新的元素,这些元素将会自动插入到开始位置索引前边
var arr = new Array();
var arr = ["孙悟空","猪八戒","沙和尚","蜘蛛精","白骨精","唐僧"];
var result = arr.splice(2,2,"白龙马","红孩儿","玉兔精");
console.log(arr);//输出'孙悟空', '猪八戒', '白龙马', '红孩儿','玉兔精', '白骨精', '唐僧' 
console.log(result);//输出'沙和尚', '蜘蛛精'

concat()

  • 可以连接两个或多个数组,并将新的数组返回
  • 该方法不会影响原函数
var arr = ["孙悟空","猪八戒","沙和尚"];
var arr2 = ["蜘蛛精","白骨精","唐僧"];
var result = arr.concat(arr2,"牛魔王");
console.log(result);//输出 '孙悟空', '猪八戒', '沙和尚', '蜘蛛精', '白骨精', '唐僧' , '牛魔王'

join()

  • 该方法可以将数组转换为一个字符串
  • 该方法不会对原数组产生影响,而是将转换后的字符串作为结果返回
  • 在join()中可以指定一个字符串作为参数,这个字符串将会成为数组中元素的连接符
var arr = ["孙悟空","猪八戒","沙和尚"];
console.log(arr.join());//输出孙悟空,猪八戒,沙和尚(默认用,连接数组内元素)
console.log(arr.join(哈哈));//输出  孙悟空哈哈猪八戒哈哈沙和尚

reverse()

  • 该方法用来反转数组(前边去后边,后边去前边)
  • 该方法会改变原数组

sort()

  • 可以对数组进行排序,默认会按照Unicode编码进行排序(因为是按照Unicode编码排序,所有可能会与自己的期望有很大出入)

  • 会影响原数组

  • 我们可以自己来指定排序顺序

    • 我们可以在sort()添加一个回调函数,来指定排序规则,

      回调函数需要定义两个形参,

      浏览器将会分别使用数组中的元素作为实参去调用回调函数

      使用哪个元素调用不确定,但肯定的是在数组中a一定在b前面

    • 浏览器会根据回调函数的返回值来决定元素的顺序

      如果返回一个大于0的值,则元素会交换位置

      如果返回一个小于0的值,则元素位置不变

      如果返回一个0,则认为两个元素相等,也不交换位置

  • 如果需要升序排列,则返回a-b,降序排列,则返回b-a

var arr = ["a","e","d","c","b"];
arr.sort();
console.log(arr);//输出'a', 'b', 'c', 'd', 'e'

var arr = [1,2,7,9,2,9,4,9,4,6,1,51,55,1,5,161,51,881,8,4];
arr.sort(function fun(a,b){
    return a-b;
});
console.log(arr);//输出[1, 1, 1, 2, 2, 4, 4, 4, 5, 6, 7, 8, 9, 9, 9, 51, 51, 55, 161, 881
]
自定义对象
  • 创建对象

1、使用new关键字调用的函数,是构造函数constructor,构造函数是专门用来创建对象的函数

var obj = new Object();
console.log(typeof obj);//返回Object

在对象中保存的值称为属性,向对象中添加属性

语法:对象.属性名 = 属性值;

var obj = new Object();
obj.name = "孙悟空";//添加一个name属性
obj.gender = "男";//添加一个gender属性
obj.age = 18;//添加一个age属性

2、使用对象字面量来创建一个对象(使用对象字面量可以在创建对象时,直接指定对象中的属性)

对象字面量的属性名可以加引号也可以不加引号,建议不加。

如果要使用一些特殊的名字则必须加引号“!@¥#@……”

语法:{属性名:属性值,属性名:属性值,…}

var obj = {};
console.log(typeof obj);//输出object
obj.name = "孙悟空";
console.log(obj.name);//输出孙悟空

var obj2 = {
            name:"猪八戒",
            age:28,
            gender:"男"
           };
console.log(obj2);//输出   猪八戒  28   男

3、使用工厂方法创建对象

通过该方法可以大批量的创造对象

使用工厂方法创建的对象使用的构造函数都是Object,所以创建的对象都是Object这个类型,就导致我们无法区分出多个不同类型的对象

function createPerson(name , age , gender) {
    var obj = new Object();
    obj.name = name;
    obj.age = age;
    obj.gender = gender;
    obj.sayName = function () {
        alert(this.name)
    }
    return obj;
}
var obj2 = createPerson("猪八戒" , 28 , "男");
var obj3 = createPerson("沙和尚" , 28 , "男");
var obj4 = createPerson("唐僧" , 38 , "男");

console.log(obj2);//输出猪八戒
obj4.sayName();//输出唐僧

构造函数

可以创建一个构造函数专门用来创建person对象的,构造函数就是一个普通的含数,创建方式和普通函数没有区别,不同的是构造函数习惯上首字母大写

构造函数和普通函数的区别就是调用方式的不同

普通函数是直接调用,而构造函数需要使用new关键字来使用

构造函数的执行流程

1.立刻创建一个新的对象

2.将新建的对象设置为函数中this,在构造函数中可以使用this来引用新建对象

3.逐行执行函数中的代码

4.将新建的对象作为返回值返回

使用同一个同一个构造函数创建的对象,我们称为一类对象,也将一个构造函数称为一个类

function Person(){
    this.name"孙悟空"
}
var per = new Person();
console.log(per)//输出不在是Object{孙悟空}而是person{孙悟空}
console.log(per instanceof person);//使用instanceof可以检查一个对象是否是一个类的实例,是true,否false,所有的对象都是Object的后代,所以检查是否是Object类时全是true
  • 读取对象中的属性

语法:对象.属性名

如果读取对象中没有的属性不会报错,会返回undefined

var obj = new Object();
obj.name = "孙悟空";//添加一个name属性
obj.gender = "男";//添加一个gender属性
obj.age = 18;//添加一个age属性
console.log(obj.name);//输出孙悟空
console.log(obj.hello);//输出undefined
  • 修改对象的属性值

语法:对象.属性名 = 新值

var obj = new Object();
obj.name = "孙悟空";//添加一个name属性
obj.gender = "男";//添加一个gender属性
obj.age = 18;//添加一个age属性
obj.name = "齐天大圣";
console.log(obj.name);//输出齐天大圣
  • 删除对象的属性

语法:delete 对象.属性名

var obj = new Object();
obj.name = "孙悟空";//添加一个name属性
obj.gender = "男";//添加一个gender属性
obj.age = 18;//添加一个age属性
delete obj.name;
console.log(obj.name);//输出undefined
属性名和属性值
  • 属性名:

    对象的属性名不强制要求遵守标识符的规范,什么名字都可以使用,但是使用时尽量按照标识符的规范去做

    如果要使用特殊的属性名(如123等数字),不能采用.的方式来操作,需要使用另一种方式

    语法:对象[“属性名”] = 属性值

var obj = new Object();
obj.var = "hello";//添加一个var属性
console.log(obj.var);//输出hello

obj.123 = 789;//报错

obj["123"] = 789;
console.log(obj["123"]);//输出789

obj["!#¥%……&#&*&%*&"] = "这就是我";
console.log(obj["!#¥%……&#&*&%*&"]);//输出  这就是我;尽量别这样

使用[]这种形式去操作属性,更加的灵活。

在[]中可以直接传递一个变量,这样变量值是多少就会读取那个属性

var obj = new Object();
obj["123"] = 789;
obj["nihao"] = "你好";
var n = "123";
console.log(obj[n]);//输出789
n = "nihao";
console.log(obj[n]);//输出  你好
  • 属性值

    JS对象的属性值可以是任意的数据类型

var obj = new Object();
obj.test = "hello";
console.log(obj.test);//输出hello
obj.test = 123;
console.log(obj.test);//输出123
obj.test = true;
console.log(obj.test);//输出true
obj.test = null;
console.log(obj.test);//输出null
obj.test = undefined;
console.log(obj.test);//输出undefined

甚至也可以是一个对象(套娃)、函数

如果一个函数作为一个对象的属性保存,那么我们称这个函数是这个对象的方法

调用函数就说调用对象的方法(method)

但是它只是名称上的区别没有其他的区别

var obj = new Object();
var obj2 = new Object();
obj2.name = "猪八戒";
obj.test = obj2;
console.log(obj);//输出{ test: { name: '猪八戒' } }   
console.log(obj.test);//输出{ name: '猪八戒' }
console.log(obj.test.name);//输出“猪八戒”

var obj = Object();
obj.name = "孙悟空";
obj.age = "18";
obj.sayName = function(){
    console.log(obj.name);
};
obj.sayName();//输出孙悟空


obj.sayName = function(){
    console.log(obj.name);
};
function fun(){
    console.log(obj.name);
};
obj.sayName();//调方法
            //只是名称的区分,本质是一样的
fun();//调函数
  • in运算符

    通过该运算符可以检查一个对象中是否含有指定的属性

    如果有则返回true,没有则返回false

    语法:

    “属性名” in 对象

    检查obj中是否含有test2的属性:

    var obj = new Object();
    var obj2 = new Object();
    obj2.name = "猪八戒";
    obj.test = obj2;
    console.log(obj);//输出{ test: { name: '猪八戒' } }   
    console.log(obj.test);//输出{ name: '猪八戒' }
    console.log(obj.test.name);//输出“猪八戒”
    console.log("test2" in obj);//obj没有test2的属性 输出false
    console.log("test" in obj);//obj有test的属性 输出true
    console.log("name" in obj);//obj有name的属性 输出true
    
枚举对象中的属性

枚举对象中的属性

使用for…in语句

for…in语句 对象中有几个属性,循环体就会执行几次

每次执行时会将对象中一个属性的名字赋值给变量

//语法
for(var 变量 in 对象){
}

var obj = {
            name:"孙悟空",
            age:18,
            gender:"男"
            address:"花果山"
           };
for(var n in obj){
    console.log("hello");//输出四次hello,因为obj对象中只有三个属性
    console.log(n);//输出name    age     gender     address
    console.log(obj[n]);//输出孙悟空  18  男  花果山
}
原型prototype

我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype

这个属性对应着一个对象,这个对象就是我们所谓的原型对象

如果函数作为普通函数调用prototype没有任何作用

当函数以构造函数的形式调用时,他所创建的对象中都会有一个隐含得属性,指向该构造函数的原型对象,我们可以通过______proto__来访问该属性

原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问到这个原型对象,我们可以将对象*有的内容,统一设置到原型对象中

当我们访问对象的一个属性或方法时,他会先在对象自身中寻找,如果有则直接使用,如果没有则会去原型对象中寻找,如果有会直接使用

以后我们创建构造函数时,可以将这些对象共有的属性和方法,统一添加到构造函数的原型对象中,作用不用分别为每一个对象添加,也不会影响到全局作用域,就可以使每个对象都具有这些属性和方法了

function MyClass(){
    
}
//向MyClass的原型中添加属性a
MyClass.prototype.a = 123;
MyClass.prototype.sayName = function(){
    alert("hello")
}
var mc = new MyClass();
var mc2 = new MyClass();
console.log(mc.__proto__ == MyClass.prototype);//输出true
console.log(mc.a);//输出123
mc.a = "我是mc中的a";
console.log(mc.a);//输出我是mc中的a
console.log(mc2.a);//输出123
mc.sayName();//输出hello
mc2.sayName();//输出hello

荐
                                                        js中的对象

使用in检查对象中是否含有某个属性时,如果对象中没有但原型中有,也会返回true

function MyClass(){
    
}
MyClass.prototype.name = "我是原型中的名字";
var mc = new MyClass();
mc.age = 18;
console.log(mc.name);//返回true

可以使用对象的hasOwnProperty()来检查对象自身是否含有属性,自身中含有该属性时返回true

MyClass.prototype.name = "我是原型中的名字";
var mc = new MyClass();
mc.age = 18;
console.log(mc.hasOwnProperty("age"));//输出true
console.log(mc.hasOwnProperty("name"));//输出false

原型对象也是对象,所以它也有原型,

当我们使用一个对象的属性或方法时,会在自身中寻找,

自身如果有,则直接使用,

如果没有则会去原型对象中寻找,如果原型对象中有则使用

如果没有则去原型的原型中寻找,直到找到Object对象的原型,

Object对象的原型没有原型,如果在Object中依然没有找到,则返回undefined

console.log(mc.__proto__.hasOwnProperty("hasOwnProperty"));//输出false
console.log(mc.__proto__.__proto__.hasOwnProperty("hasOwnProperty"));//输出true,说明hasOwnProperty在原型的原型中

本文地址:https://blog.csdn.net/xing_kai_kai/article/details/107265275