是“键值对”的集合,表示属性和值的映射关系
定义方法
方法1:字面量
var obj1 = {
};
方法2:new关键字
var obj2 = new Object();
属性
特别地,若属性名不符合JS标识符命名规范,则需用引号包裹
var xiaoming = {
name: '小明',
age: 12,
sex: '男',
hobbys: ['足球', '游泳', '编程'],
'favorite-book': '舒克和贝塔'
};
访问
用“点语法”
特别地,若属性名不符合JS标识符命名规范,则需用方括号访问
xiaoming['favorite-book'];
若属性名以变量形式存储,则需要方括号访问
var obj = {
a: 1,
b: 2,
c: 3,
};
var key = "b";
console.log(obj.key); //undefined
console.log(obj[key]); //2
创建
若对象本身无某属性值用点语法赋值时,属性会被创建
var obj={
a:10
};
obj.b=40;
删除
用delete操作符
var obj={
a:1,b:2
};
delete obj.a;
方法
属性值是函数的属性
var xiaoming={
name: '小明',
age: 12,
sex: '男',
hobbys: ['足球', '游泳', '编程'],
'favorite-book': '舒克和贝塔',
sayHello:function(){
console.1og('你好,我是小明,今年12岁,我是个男生');
}
};
调用
用“点语法”
遍历对象
for…in…循环
for(var k in obj){
console.log('属性'+k+'的值是'+obj[k]);
}
ES6中还有新方式
复制对象
对象属引用类型值
对象的浅克隆
只克隆对象的“表层”
若对象属性值是引用类型值,则不能进一步克隆,只传递引用
使用for…in…循环即可实现对象的浅克隆
对象的深克隆
克隆对象的全貌,不论对象的属性值是否又是引用类型值,都能将它们实现克隆
和数组的深克隆类似,对象的深克隆需要使用递归
构造函数
用new调用一个函数,这个函数就被称为“构造函数”
Javascript的构造函数可类比于OO语言中的“类”,写法类似,但和真正OO语言还是有本质不同,在后续课程还将看见Js和其他OO语言完全不同的、特有的原型特性
作用
用来“构造新对象”,它内部的语句将为新对象添加若干属性和方法,完成对象的初始化
用法
function People(name, age) {
this.name = name;
this.age = age;
this.sayHello = function () {
console.log("我是" + this.name + ",我" + this.age + "岁了");
};
console.log(this);
}
var xiaoming = new People("小明", 18);
xiaoming.sayHello();
调用
用new关键字调用,否则不能正常工作,正因如此,开发者约定构造函数命名时首字母要大写
机理
1)函数体内会自动创建出一个空白对象
2)函数的上下文(this)会指向这个对象
3)函数体内的语句会执行
4)函数会自动返回上下文对象,即使函数没有return语句
类
描述对象有哪些属性和方法,不具体指明属性的值
◆Java、C++等是“面向对象”(object-oriented)语言;
◆JavaScript是“基于对象”(object-based)语言;
注:
面向对象-特点:封装,继承,多态,缺一不可;
基于对象-特点:封装
“基于对象”使用一些封装好的对象,调用对象的方法,设置对象的属性,但无法让程序员派生新对象类型;面向对象实现了“继承和多态”,而“基于对象”没有实现
原型rototype
普通函数来说的prototype属性没有任何用处
而构造函数的prototype属性是实例的原型
//类1:人类
function People(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
People.prototype.sayHello = function () {
console.log("我是" + this.name + "我今年" + this.age + "岁了");
};
People.prototype.sleep = function () {
console.log(this.name + "开始睡觉");
};
//类2:学生
function Student(name, age, sex, school, studentNumber) {
this.name = name;
this.age = age;
this.sex = sex;
this.school = school;
this.studentNumber = studentNumber;
}
//类2继承类1
Student.prototype = new People();
//子类可定义特有属性和方法
Student.prototype.study = function () {
console.log(this.name + "正在学习");
};
Student.prototype.exam = function () {
console.log(this.name + "正在考试,加油!");
};
// 子类可重写父类的方法
Student.prototype.sayHello = function () {
console.log("敬礼,我是" + this.name + "我今年" + this.age + "岁了");
};
var hanmeimei = new Student("韩梅梅", 9, "女", "慕课小学", 100556);
hanmeimei.study();
hanmeimei.sayHello();
hanmeimei.sleep();
var laozhang = new People("老张", 66, "男");
laozhang.sayHello();
原型上的方法各实例共享
区别:对象上的方法各实例不共享,占用不同内存
function People(name, age) {
this.name = name;
this.age = age;
// 方法写在对象
// this.sayHello = function () {
// console.log("我是" + this.name + ",我" + this.age + "岁了");
// };
console.log(this);
}
// 方法写在原型
People.prototype.sayHello = function () {
console.log("我是" + this.name + ",我" + this.age + "岁了");
};
var xiaoming = new People("小明", 18);
xiaoming.sayHello();
继承
描述两个类之间的“is a kind of”关系,比如学生类和人类之间构成继承关系
People是“父类”(或“超类”、“基类”);
Student是“子类”(或“派生类”)
原型链
是实现继承的方法
子类继承父类全部属性和方法,也可定义特有的属性和方法
在今后学习ES6时,将介绍新的实现继承的方法
原型链查找
JavaScript规定:实例可以打点访问它的原型的属性和方法,这被称为“原型链查找"
原型链遮蔽
function People(name, age) {
this.name = name;
this.age = age;
}
People.prototype.nationality = "中国";
var tom = new People("Tom", 12);
//遮蔽原型链
tom.nationality = "美国";
console.log(tom.nationality); //美国
原型链终点
是Object.prototype
上升到面向对象
本质:定义不同的类,让类的实例工作
优点:程序更清晰、代码结构更严密、更健壮、更利于维护
使用场合:组件化思维
案例1:100个红绿灯
类:TrafficLight
属性:当前颜色color、DOM元素dom
方法:初始化init()、切换颜色changecolor()、绑定事件bindEvent()
<style>
#box img {
height: 80px;
}
</style>
<body>
<div id="box"></div>
<script>
function TrafficLight() {
this.color = 1;
this.init();
}
TrafficLight.prototype.init = function () {
this.dom = document.createElement('img');
this.dom.src = 'images/' + this.color + '.jpg';
box.appendChild(this.dom);
}
var box = document.getElementById('box');
var tl = new TrafficLight();
console.log(tl);
</script>
</body>
案例2
JS的内置对象
包装类
Number()、String()和Boolean()分别是数字、字符串、布尔值的“包装类";
目的:让基本类型值可从它们的构造函数的prototype上获得方法
实例是object类型
PrimitiveValue属性-存储它们的本身值
new出来的基本类型值可以正常参与运算
Math对象
1)幂、开方
Math.pow()
Math.sqrt()
2)向上取整和向下取整
Math.ceil()
Math.floor()
3)四舍五入
4)最值
Math.max()
Math.min()
console.log(Math.max(6,2,9,4));//9
console.1og(Math.min(6,2,9,4));//2
问题:求数组的最大值
Math.max()参数要罗列
apply()可指定函数的上下文,且将数组零散化
var arr = [5, 3, 6, 4, 7, 2, 9, 10];
//方法1:用apply(不可用call)
console.log(Math.max.apply(null, arr));
//方法2:展开运算符(ES6特有)
console.log(Math.max(...arr));
5)随机数
Math.random()
可得到0~1之间的小数
得到[a,b]区间内的整数:parseInt(Math.random()*(b-a+1))+a
Date对象
new Date()可得当前时间的日期对象,是object类型值
new Date(2020,11,1)可得指定日期的日期对象,第二个参数表示月份,从0开始,11表示12月
方法 | 功能 |
---|---|
getDate() | 得到日期1~31 |
getDay() | 得到星期0~6 |
getMonth() | 得到月份0~11 |
getFullYear() | 得到年份 |
getHours() | 得到小时数0~23 |
getMinutes() | 得到分钟数0~59 |
getSeconds() | 得到秒数0~59 |
时间戳
表示距离1970年1月1日零点的毫秒数
与日期对象可相互转换:
1)日期对象变为时间戳
getTime()
Date.parse()
2)时间戳变为日期对象
new Date()
var d = new Date();
//1)日期对象变为时间戳
var timestamp1 = d.getTime();//精确到毫秒
var timestamp2 = Date.parse(d);//精确到秒
console.log(timestamp1);
console.log(timestamp2);
// 2)时间戳变回日期对象
var dd = new Date(1601536565000);
console.log(dd);
console.log(dd.getFullYear());
类数组对象
键名为自然数序列(从0开始),且有length属性的对象
例如:arguments