一:对象的声明与调用
方法1:利用对象字面量创建对象
var obj={}; 创建了一个空对象
属性和值之间用: 结尾用,
:后面跟了一个匿名函数`
var obj={name:"李旭亮",sex:"男",age:'22',sayHi:function(){console.log('hello!');}}
使用对象
调用对象属性:【1】对象.属性名 【2】对象名[‘属性名’]
console.log(obj.age); console.log(obj['name']);// 调用方法: 对象名.方法名();obj.sayHi();
运行结果:
方法2:new Object()
<script>p=new Object();///创建一个空的对象p.name="李旭亮";p.age="22";p.sex="男";p.sayHi= function(){console.log("hi~");}// 利用 等号=赋值的方法,添加对象的属性和方法// 每个属性和方法之间,用分号结束console.log(p.age);console.log(p.sayHi());</script>
运行结果:
方法3:利用构造函数创建对象
构造函数:是一种特殊的函数,主要用来初始化对象
使用场景:常规的 … 语法允许创建一个对象。比如我们创建了佩奇的对象,
继续创建乔治的对象还需要重新写一遍,此时可以通过构造函数来快速创建多个类似的对象。
又例如:
实例成员:
通过构造函数创建的对象称
为实例对象,实例对象中的属性和方法
称为实例成员(实例属性和实例方法)
说明
1.为构造函数传入参数,创建结构相同但值不同的对象
2.构造函数创建的实例对象彼此独立查不影响
// 定义构造函数
function People(name, age, gender) {this.name = name;//实例成员this.age = age;this.gender = gender;
}
// 定义对象
//实例化 lxl和yll都是实例对象
let lxl = new People('李旭亮', 18, '男');
let yll = new People('叶林林', 18, '女');
//lxl.gender 实例对象lxl的实例成员
console.log(lxl.gender);//男
静态成员:
构造函数的属性和方法
被称为静态成员(静态属性和静态方法)
例如Data.now();Data是构造函数,now()是静态属性
说明:
1.静态成员只能构造函数来访问
2.静态方法中的this指向构造函数
// 定义构造函数
function Pig(name) { this.name = name;
}
// 构造函数的属性和方法称为静态成员
Pig.weight=200;//静态属性
Pig.sleep=function(){//静态方法console.log('睡觉');
}
// 静态成员只能构造函数来访问
console.log(Pig.weight);//200let p1=new Pig('lll');
console.log(p1.sleep);//undefined
对象的基本操作
增删改查
//增 增加地址
obj.address="中国";
console.log(obj);
// 删 删除名字
delete obj.name;
console.log(obj);
// 改 将年龄修改为100
obj.age=100;
console.log(obj);
1.1关于对象的注意点:
在js对象中,如果属性名和属性值形同,那么就可以省略属性值。
let age = 30
const person = {// age: age,age,
}
console.log(person.age);//30
对象与函数的一点区别:
let data = {x:1,y:2,
}
const a=data;
const b=data;
function data() {return {x: 1,y: 2,}
}
const a=data();
const b=data();console.log(typeof data());//对象
console.log(typeof data);//函数
console.log(typeof a);//对象
// 由此观之,对象还是函数,主要看他的输出结果
二:对象的遍历
for in对数组进行遍历
let arr=['red','green','blue'];
for (const key in arr) {console.log(key);//'0' '1' '2' 像是数组的序号,但这是字符串型的console.log(arr[key]);//'red' 'green' 'blue'
}
for in遍历对象
先创建一个对象
let lxl={name:'李旭亮',sex:'男',age:22,address:'CN',study:function(){console.log("正在学习");}
}
遍历:
for (const key in lxl) {console.log(key);
}
lxl[key]------类似于数组的 数组名[序号] arr[i]
for (const key in lxl) {console.log(lxl[key]);
}
数组对象的遍历
let student = [{ name: '小明,', age: 18, gender: '男', address: 'CN' },{ name: '小红', age: 34, gender: '女', address: 'USA' },{ name: '小白', age: '23', gender: '男', address: '河南省' },{ name: 'lxl', age: 100, gender: '男', address: 'UK' ,study:function(){console.log("2023.2.12");}}
];
for (let i = 0; i < student.length; i++) {for (const key in student) {//student[i]相当于数组名console.log(student[i].address);}
}
三:对象解构
对象解构是将对象属性和方法快速批量赋值给一系列变量的简洁语法
基本语法:
1.赋值运算符 = 左侧的{}用于批量声明变量,右侧对象的属性值将被赋值给左侧的变量
2.对象属性的值将被赋值给与属性名相同的变量
const { uname1, age1 } = { uname1: '李旭亮', age1: '18' };
3.注意解构的变量名不要和外面的变量名冲突否则报错
4.对象中找不到与变量名一致的属性时变量值为 undefined
const { uname2, age1 } = { uname1: '李旭亮', age1: '18' };
console.log(`我的名字:${uname2}`);
对象解构例子:
// 对象解构的写法
obj = {
uname: '叶林林',
age: 18
}
const { uname, age } = obj;
console.log(uname);//叶林林const { uname2, age1 } = { uname1: '李旭亮', age1: '18' };
console.log(`我的名字:${uname2}`);//undefined
5.对象解构的更名 旧变量名:新变量名
const { uname1:uname2, age1 } = { uname1: '李旭亮', age1: '18' };
console.log(`我的名字:${uname2}`);//我的名字:李旭亮
四:数组对象的解构
比对象解构多加了一个[ ]
const fairy = [{uname: '林宝宝',age: 18,home: '新乡'}
];const [{ }] = fairy;
console.log(`仙女是${uname}`);//仙女是叶林林
这个输出结果不是林宝宝,因为上面还有一个uname,重名了。
五:多级对象解构
const pig = {name: '佩奇',age: 6,family: {mother: '猪妈妈',father: '猪爸爸',brother: '乔治',}
}
// 多级对象解构
const { name, age, family: { mother, father, brother } } = pig;
console.log(mother);//猪妈妈
六:数组对象多级解构
const pig = [{name: '佩奇',age: 6,family: {mother: '猪妈妈',father: '猪爸爸',brother: '乔治',}}
]
// 多级对象解构
const [{ name, age, family: { mother, father, brother } }] = pig;
console.log(mother);//猪妈妈
七:Object静态方法
定义一个数组
let arr = [1, 2, 3, 4, 5];
没有初始值,计算这个数组的连加和
const total = arr.reduce(function (prev, current) {return prev + current;
})
console.log(total);//15
有初始值
const arr1 = arr.reduce(function (prev, current) {return prev + current;
}, 100)
console.log(arr1);//115
箭头函数的写法
const total3 = arr.reduce((prev, current) => prev + current, 1000);
console.log(total3);//1015
八:原型对象protopyte
目标:能够利用原型对象实现方法共享
- 构造函数通过原型分配的函数是所有对象所 共享的
- JavaScript 规定,
每一个构造函数都有一个 prototype 属性
,指向另一个对象,所以我们也称为原型对象 - 这个对象可以挂载函数,
对象实例化不会多次创建原型上函数
,节约内存 - 我们可以把那些不变的方法,直接定义在 prototype 对象上,这样所有对象的实例就可以共享这些方法
- 构造函数和原型对象中的this 都指 实例化的对象
function Star(uname, age) {this.uname = uname;this.age = age;this.sing=function(){console.log('唱歌');}
}
const a=new Star('a',12);
const b=new Star('b',120);
console.log(a.sing);//输出是一个函数
// 对象a的sing方法和对象b的sing方法不一样,每个新的对象,
// 都是一个新的sing方法,但是每个对象的sing方法是一个的,会浪费内存
console.log(a.sing===b.sing);//false
用原型对象prototype可以解决这个问题
Star.prototype.sport=function(){console.log('运动');
}
console.log(a.sport);//也是一个对象
console.log(a.sport===b.sport);//true
8.1、对象原型与原型对象
对象原型 __proto__
原型对象 prototype
对象都会有一个属性 __proto__
指向构造函数的 prototype原型对象,
之所以对象可以使用构造函数prototype原型对象的属性和方法,
就是因为对象有 __proto__
原型的存在。
// 定义构造函数
function Star(name = '刘德华', age = 55) {this.name = name;this.age = age;
}// 用原型对象创建公共方法
Star.prototype.sing=function(){console.log('唱歌!');
}// 实例化对象
const p = new Star('lxl',34);console.log(p.__proto__);//{sing: ƒ, constructor: ƒ}
console.log(Star.prototype);//{sing: ƒ, constructor: ƒ}// 对象身上,系统自己添加一个 __proto__指向我们构造函数的原型对象
console.log(p.__proto__===Star.prototype);//true
__proto__
对象原型和原型对象prototype是等价的
__proto__
对象原型的意义就在于为对象的查找机制提供一个方向,或者说一条路线,但是它是一个非标准属性因此实际开发中,不可以使用这个属性,它只是内部指向原型对象prototype
// 构造函数和原型对象中的this 都指 实例化的对象
let thisGouzao;
let thisYuanxing;
function Star(uname, age) {this.uname = uname;this.age = age;thisGouzao = this;
}
Star.prototype.sport = function () {thisYuanxing = this;
}
const lxl = new Star('李旭亮', 100);
console.log(lxl.sport());//undefined
console.log(thisGouzao);//{uname: '李旭亮', age: 100}
console.log(thisYuanxing);//{uname: '李旭亮', age: 100}
console.log(thisGouzao === lxl);//true
console.log(thisYuanxing === lxl);//true
console.log(thisGouzao === thisYuanxing);//true
九:利用原型自定方法
function a() {
}
console.log(typeof a);//function
console.log(typeof Date);//function
console.log(typeof Array);//function
Date,Array和a其实是一样的,都是方法
// 需求1:制造数组求最大值方法
Array.prototype.max = function () {// ...this指向实例对象 数组是对象// console.log(...this);//1 2 3return Math.max(...this);
}
const arr = [1, 2, 3];
console.log(arr.max());//3// 需求1:制造数组求和方法
Array.prototype.sum=function(){ const a= this.reduce(function(prev,current){return prev+current;})return a;
}
console.log(arr.sum());//6
十:class与类的继承
// 定义一个人类
class Person {// 构造器constructor(name, age) {this.name = name;this.age = age;}// 方法hello() {console.log('你好啊');}
}
// 实例化对象
let lxl = new Person('李旭亮', 23);
console.log(lxl.age);//23
// 对象的继承
class Woman extends Person {// 构造器constructor(name, age, grade) {// 通过super调用Person类的构造器,进行赋值super(name, age);this.grade = grade;}// 自己的方法sleep() {console.log('我喜欢睡觉!');}
}
// 实例化对象
let yll = new Woman('叶林林', 20, 102);
console.log(`名字:${yll.name},年龄:${yll.age},成绩:${yll.grade}`);
十一:对象中的函数function和:可以省略
obj={name:'yll',age:23,// doing:function(){// console.log('我在学习');// }doing(){console.log('在对象里面,方法可以省略function和:');}
}
obj.doing()
对象、函数中this的指向
const obj={name:'lxl',age:453,doing:function(){console.log('----------doing:function()--------------');console.log(this);},study:()=>{console.log('---------------study:()=>-------------------');console.log(this);},sleep(){console.log('------------------sleep()----------------------');console.log(this);eat:()=>{console.log(this);}}
};
obj.doing();
obj.study();
obj.sleep()