※对象
万物皆可对象 分为:
-
具体对象:是一个具体的事物,对象由属性和方法构成 无序的 对象都可以添加属性
-
一类对象:是一个大概类型事物
作用:让结构更清晰 比起数组可读性好 调用更便利
属性:事物的特征 (名词)
- 属性在对象里不需要声明 变量需要声明并赋值 调用不同
方法:事物的行为 (动词)
- 方法在对象里 函数是单独存在单独声明 调用方法不同
√ 面向的对象的编程思维:
我们再实现某个功能的时候,不应该考虑第一步该做什么,第二该做什么,而是要考虑好在这个业务中,存在哪些对象,再来考虑这些个对象应该拥有哪些属性和方法,最后在考虑这些个对象之间存在什么样的关系
创建对象方法:
※字面量:
字面量创建:
var obj = {
//特征属性
nuame(属性名): '张三丰',(值)
age: 18,
sex: '男',
方法名: funcition() {
//行为方法
}
};
// 调用对象属性 对象名.属性名
1. console.log(obj.nuame)
// 当属性名不符合规范 使用中括号
2. console.log(obj['nuame'])
// 调用方法 对象名.方法()
obj.方法名()
- 采用键值对形式 属性名和冒号之间不能有空格
- 特征属性之间逗号隔开
- 冒号后面是匿名函数
- 属性名实际上是字符串 不符合规范用单引号包起来
.
语法等于访问某个对象的某个值 语义=xx的xx
.和[]的区别
对象里面都是以键值对的形式存在,键实际上就是一个标准的字符串,如果这个键符合命名规范的变量名,那么就可以直接通过点.
语法来访问,如果不符合命名规范的变量名,就要用中括号[]
的形式来访问了
// 调用对象属性 对象名.属性名
1. console.log(obj.nuame)
// 当属性名不符合规范 使用中括号
2. console.log(obj['nuame'])
new 方法:
// 语法:
var obj = new Object(); // 创建了一个空的对象
obj.属性名 = 值;
obj.方法名 = function() {
console.log('hi~');
}
// 调用属性和字面量相同
// 调用方法
obj.方法名();
-
创建一个空对象
-
设置键值对赋值 =赋值 属性之间分号结束
-
调用和字面量相同
※构造函数:
构造函数创建对象 泛指某一大类 用来给对象初始化变量
目的: 创建对象内的结构相同 构造函数可以重复利用相同结构
和普通函数不同 构造函数内封装的是对象 和new运算符一起使用
function 构造函数名() {
this.属性名 = 值
this.方法名 = function() {
//函数体
}
}
// 属性调用
// 定义一个变量
var 变量名 = new 构造函数名() //调用返回的是对象
// 方法调用
变量名.方法名()
注:
- 构造函数名首字母大写
- 构造函数不需要return返回值
- 调用构造函数要使用new
new关键字执行过程(不需要return原因)
-
new 在构造函数中创建了一个空对象
-
这个this指向新对象
-
构造函数代码 this给新对象挂载属性
-
返回这个新对象
构造函数和对象的关系
- 构造函数可以理解成一类对象的模板
- 通过new 构造函数创建出来的对象可以理解成用这个模板生成的实例
- 构造函数里面的this就指向这个新创建出来的对象
※遍历对象 for…in
对数组和 对象 进行遍历
for (var k in obj) {
console.log(k);//输出的是属性名
console.log(obj[k]);//obj[k]输出属性值
}
// 输出属性值必须是中括号 .会找不到k出现undefined
- 属性名一般用k 或者 key
- k就是构造函数里面的属性名
- 通过obj[k]访问属性名中的值
- k数组里面的属性名是数字顺序会按照数字来排列
内置对象
js自带内置的一些常用的基本功能的对象
优点:帮助快速开发
[查阅文档 MDN][https://developer.mozilla.org/zh-CN/]
如何学习对象中的方法
- 查阅该方法的功能
- 查看参数意义和类型
- 查看返回值意义和类型
- 通过demo进行测试使用
- 中括号包括的参数表示[可有可无]
Math对象
不是构造函数 具有数学和函数的属性和方法
// 语法: Math.Math对象()
// 三种取值方法
floor() // 向下取整 地板
ceil() // 向上取整 天花板
round() // 四舍五入 .5特殊 往大取 -值也是
// PI 圆周率
abs() // 绝对值 取正
max() // min() 最大/最小值
random() // 0-未满1内的随机数 .5特殊 -1.5 = -1往大取
随机点名案例
// 随机数公式
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min
}
日期对象 Date
date时间从1970年1月1日开始计算
// Date一个构造函数 需要new来创建
var 变量名 = new Date() // date为空是获取系统当前时间
var 变量名 = new Date(x,x,x) // 数字型 返回日期月份要大1个月
var 变量名 = new Date('xxxxx') // 常用字符串
日期格式化:
// 实例化日期对象:
var 变量名 = new Date()
// 调用:
变量名.getFullYear()
注意点:
- getDay:星期日写在第一位 因为getday星期日下标是0开头
- getMonth :因为是从0开始 所以获取的月份少一个月 使用时+1
毫秒数(时间戳)
获取1970到现在的毫秒数
// 实例化Date对象
var now = new Date()
// 1. 用于获取对象的原始值
console.log(date.valueOf())
console.log(date.getTime()) // 常用1
// 2. 简单写可以这么做
var now = + new Date()
// 2.1 等于以下内容:
var now = new Date() // 常用1
now.getTime()
// 3. HTML5中提供的方法,有兼容性问题
var now = Date.now() // 常用2
获取当前时间秒的毫秒 getMilliseconds ()
console.log((new Date()).getMilliseconds())
※倒计时案例
代码不能略
// 1. 思路:输入的时间减去现在的时间就是剩余的时间,即倒计时 ,但是不能拿着时分秒相减,比如 05 分减去25分,结果会是负数的。
// 用时间戳来做。用户输入时间总的毫秒数减去现在时间的总的毫秒数,得到的就是剩余时间的毫秒数。
// 2. 核心算法
function countDown(time) {
// var nowTime = +new Date(); // 返回的是当前时间总的毫秒数
var nowTime = new Date(); // 返回的是当前时间总的毫秒数
console.log(nowTime.getTime());
var inputTime = +new Date(time); // 返回的是用户输入时间总的毫秒数
var times = (inputTime - nowTime) // 1000
// times是剩余时间总的秒数
// 3. 格式化时间
var d = parseInt(times / 60 / 60 / 24); // 天
d = d < 10 ? '0' + d : d;
var h = parseInt(times / 60 / 60 % 24); //时
h = h < 10 ? '0' + h : h;
var m = parseInt(times / 60 % 60); // 分
m = m < 10 ? '0' + m : m;
var s = parseInt(times % 60); // 当前的秒
s = s < 10 ? '0' + s : s;
return d + '天' + h + '时' + m + '分' + s + '秒';
}
// 4. 调用格式化函数来格式化时间戳
console.log(countDown('2019-5-1 18:00:00'));
var date = new Date();
console.log(date);
※数组 Array
创建数组:
1.字面量方式
var arr = [数值1,数值2,数值3]
// 打印输出
console.log(arr[0]); //打印下标0的数值
2. new Array()创建 //不推荐
var 数组名 = new Array(数组长度);
var 数组名 = new Array(数值元素1,数值元素2);
// 注:只有一个参数表示数组长度 有两个参数表示 两个数值元素
检测是否为数组
方法1:instanceof 运算符
// 语法: 数组名/arr instanceof Array
var arr = [1,2,3]
var arr2 = '1,2,3'
document.write(arr instanceof Array) // ture
document.write(arr2 instanceof Array) // false
// 检测arr是不是array中建立出来的数组 不仅仅可以检测是否为数据 还可以检测是否为构造函数
// 返回值是布尔值
*方法2:Array.isArray 属于静态 prototype下属于动态
// 语法: Array.isArray(参数)
var arr = [1,2,3]
var arr2 = '1,2,3'
document.write(Array.isArray(arr)) // ture
document.write(Array.isArray(arr2)) // false
// 返回值布尔值
两者区别: Array.isArray h5新增 优先于instanceof
※添加删除数组元素方法
方法名 | 描述 | 返回值 | 是否改变原数组 |
---|---|---|---|
arr.push() | 数组末尾追加项目 | 数组长度 | 是 |
arr.unshift() | 数组前追加项目 | 数组长度 | 是 |
arr.splice(2,0,6) | 添加或删除项目 | 被删除的数组长度 | 是 |
arr.pop() | 数组末尾删除项目 | 被删除的数组项目 | 是 |
arr.unshift() | 数组前删除项目 | 被删除的数组项目 | 是 |
添加方法:
// 1.push()
var arr = [1,2,3,4]
var arr2 = arr.push(2)
console.log(arr) // 12342
console.log(arr2) // 返回值长度
// push() 在数组末尾添加一个或多个元素 参数写在括号内 返回值是新数组长度 原数组也会发生变化
// 2.unshift()
var arr = [1,2,3,4]
var arr2 = arr.unshift(2)
console.log(arr) // 21234
console.log(arr2) // 返回值 长度
// unshift() 在数组前面追加元素 返回值是新数组的长度 会改变原数组 其他和push相同
删除方法:
// 1.pop() 最后一个数组元素
var arr = [1,2,3,4]
var arr2 = arr.pop()
console.log(arr) // 12634
console.log(arr2) // 返回值 0时为空
// 无参数 返回值是删除元素 改变原数组
// 2.shift() 删除第一个数组元素
var arr = [1,2,3,4]
var arr2 = arr.unshift(2)
console.log(arr) // 234
console.log(arr2) // 返回值 长度
// 其他和pop相同
添加和删除的方法:
// 1.splice() 向数组中添加或删除项目
var arr = [1,2,3,4]
var arr2 = arr.splice(2,0,6)
console.log(arr) // 12634
console.log(arr2) // 返回值 0时为空
// 数组名.splice(必须/插入位置的下标,必须/删除数量,可选/插入的元素,...) ,逗号隔开 可以插入多数量 返回值是被删除的元素 改变原数组
数组排序 reverse/sort
// 1.reverse() 翻转数组
var arr = [1,2,3,4]
var arr2 = arr.reverse()
console.log(arr) // [4,3,2,1]
console.log(arr2) // 返回值 [4,3,2,1]
//只改变原数组 不会返回新数组
// 2.sort() 冒泡排序
// 2.1 创建数组
var arr = [1,2,3,4,5,6,7]
// 2.2 利用函数制定规则
function max(a,b){ return b-a }
// 2.3 数组调用方法 方法使用函数规则
console.log(arr.sort(max)) // 7654321
// 注:
// 无参时会按照字符编码的顺序进行排序 前提是数组内的项目都是字符串
// 在需要其他标准排序时需要使用函数来定义详细排序规则 ↓
注:sort方法需要传入参数来设置升序、降序排序
- 如果传入“function(a,b){ return a-b;}”,则为升序
- 如果传入“function(a,b){ return b-a;}”,则为降序
求数组内数字的和 reduce
// 1. reduce 可以取数组属性内的值从左向右进行相加
// 1.1 创建数组
var arr = [1,2,3,4,5,6,7]
// 1.2 制定函数规则
function add (a,b){ // 函数的第一参数是初始值 第二参数是当前值 两者参数是必填的 当前值会因为再一次的调用 变为初始值
return a + b
}
// 1.3 数组调用方法 方法调用函数规则
console.log(arr.reduce(add)) // 数组综合 28
详细的执行过程:
※数组索引号 indexOf
作用:根据索引号查找数组中项目出现的位置
// 1. 数组名.indexOf(数组元素) 从头开始查找
var arr = [1,6,2,3,4,5,6]
console.log(arr.indexOf(6)) // 1 返回第一次出现6的索引
console.log(arr.indexOf(6,3)) // 6 返回指定位置后 第一次出现的索引
// 没有找到则返回-1 字符串也是相同
// 2. 数组名.lastindexOf(数组元素) 从后开始查找
var arr = [1,6,2,3,4,5,6]
console.log(arr.lastindexOf(6)) // 1 返回第一次出现6的索引
console.log(arr.lastindexOf(6,3)) // 6 返回指定位置后 第一次出现的索引
// 没有找到则返回-1 字符串也是相同
-
返回指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1。
-
返回从 fromIndex 位置开始查找指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1。
数组去重案例
先遍历旧数组 indexOf查找旧数组 返回值等于-1就存入到新数组中
var arr = [1,2,3,4,5,5,6,2]
var arr2 = []
var arr3 = []
for(var i = 0; i<arr.length; i++){
// 为什么要使用arr2新数组去查找?
// 将arr2和arr中的项目一一比对 不存在返回-1时说明是不重复的项目 就push到新数组中 一开始的arr2是空数组 在找到过一次-1时 数组中会存放进新项目 再次更据此数组去循环 保证了数组中项目的唯一性
if(arr2.indexOf(arr[i]) == -1) {
arr2.push(arr[i])
}else{
// 重复的数组项目
arr3.push(arr[i])
}
document.write('循环中',arr2)
}
document.write('结束后',arr2)
document.write('结束后重复元素',arr3)
注: set es6中常用的数组去重方法 因为set集合没有序列号 所以不会有重复的值存在
数组转换为字符串 toString/join
- toString()
// 数组名.toString () 把数组转换为字符串
var arr = [1,2,3,4,5]
console.log(arr.toString()) // 1,2,3,4,5
// 返回值是被转换为字符串的值
- join()
// 数组名.join () 可以用分隔符连接
var arr = [1,2,3,4,5]
console.log(arr.join()) // 1,2,3,4,5
console.log(arr.join('!')) // 1!2!3!4!5
// 括号内''内容为分隔数组的分隔符 无参默认逗号 可传空字符串
数组的其他方法
方法名 | 说明 | 返回值 |
---|---|---|
concat() | 连接两个或多个数组 不影响原数组 | 一个新数组 |
slice(star,end) | 数组截取slice(begin,end) 不修改原数组 | 被截取的新数组 |
splice(star,end) | 数组删除splice(序列号位置,删除的个数) 影响原数组 | 返回被删除的数组 |
字符串对象
基本包装类型: 本身是基本类型 在代码的执行做个中拥有了方法和属性 就不再是基本类型了 称为基本包装类型=复杂数据类型
目的: 为了让普通变量能直接调用属性和方法 将其转换为包装类
注: 字符串不可变 重复赋值只会新开一个位置 原本的值会保留 大量拼接字符串会卡顿
基本包装类型走向
通过new将定义的str变成了字符串对象 让其拥有了属性和方法
string:创建字符串 会放入字符串池 字符串池(为了防止系统中产生大量字符串) 当创建字符串时 会向池中检查是否含有相同的字符串
new String:会new一个对象 并创建str字符串 new的字符串对象并不会放入字符串池
※根据字符返回位置 indexOf
利用数组索引方法查找出数组中
变量名.indexOf(‘要查找的字符’, [起始的位置下标])
※根据位置返回字符 charAt/charCodeAt
- charAt()
// str.charAt(返回位置的下标) 从0开始计算 不能负数
var s = "xxxx23xx"
document.write(s.charAt(5)) // 3
// 数字在做条件条件判断时 只要不是0 那么就是true
- charCodeAt()
// str.charCodeAt(0) 返回索引号对应的ASCII字符
var str="Hello world!"
document.write(str.charCodeAt(1)) // 101 字符编码
// 作为判断用户按下了哪个键
※字符串操作方法 slice
注:substr没有被ecmascrip标准化 少用
substring 是一个方法 用于提取字符串介于两个指定下标之间的字符
// 语法:stringObject.substring(start,stop)
var str="Hello world!"
document.write(str.substring(3,7))
document.write(str.slice(3,7))
// 输出:lo w
// 返回值:新的字符串 原数值不受影响
// substring、slice区别 slice可以用负数
// 可以只写一个参数取值取到字符串结束位置
注意点:
- start必填 括号内除了slice 其他必须是非负的整数
- 从0开始往后取 包含空格
- stop最后一位不取所以需要+1
- start数值比stop大 方法会在提取前交换这两个参数的值
替换字符 replace
应用场景:过滤敏感词
// 数组名.replace(/被替换的字符串/,要替换为的字符串)
var str="Hello world!"
var str2 = str.replace(/world/, 123)
document.write(str2) // Hello 123!
// 注意点: 被替换的数值需要被//包裹 只替换第一个找到的
// 替换全部使用//g 替换小写//i
切分字符串 split
作用:将字符以指定字符来切分为数组 返回值是数组
// 数组名.split('分割字符',返回数组长度/可选)
var str="Hello world!"
document.write(str.split(" ")) // Hello,world!
// 切最后一次字符时 会在最后产生一个空的字符串
字符串转换数组
// 数组名.toUpperCase() 转换为大写
var str="Hello world!"
document.write(str.toUpperCase()) // HELLO WORLD!
// 数组名.toLowerCase 转换小写
var str="Hello world!"
document.write(str.toLowerCase()) // hello world!
简单、复杂类型
简单类型(基本数据类型、值类型)
在存储时变量中存储的是值本身,包括string ,number,boolean,undefined,null 放在栈里
传参: 传的是值
自己传自己的值 赋值给其他值后 其他值自己产生一个内存 产生变化只变化自己
复杂类型
一般用new定义都是复杂类型
实例放在堆里面 内存地址存在栈里面 地址有多条 实例模板只有一个 实例改变 其他引用这份实例的也会改变
传参: 传的是地址