荐 js中的对象
js中的对象
除了五种基本数据类型外还有一个引用数据类型:Object 对象(以后我们看到的值,只要不是五种基本数据类型的,全都是对象)
如果使用基本数据类型的数据,我们所创建的变量都是独立的,不能成为一个整体,例如:
var name = "孙悟空";
var gender = "男";
var age = "18";//这三个数据毫无关联,互相独立
-
Js中的变量都是保存到栈内存中的
基本数据类型的值直接在栈内存中存储,值与值之间是独立存在的,修改一个变量不会影响到其他变量
对象是保存在堆内存中,每创建一个新的对象,就会在堆内存中开辟出一个新的空间,而变量保存的是对象的内存地址(对象的引用),如果两个变量保存的是同一个对象引用,当一个对象通过一个变量修改属性时,另一个也会受影响
当给其中一个对象赋值时,会切断与之前地址的连接
当比较两个两个基本数据类型时,就是比较的值,而比较两个引用数据类型时,是比较对象的内存地址,如果两个对象的值是一模一样的,但地址不同,也会返回false
-
对象属于一种复合的数据类型,在对象中可以保存多个不同类型的属性
-
对象的分类
-
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
使用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
下一篇: 主流的CMS自助建站系统哪个好