01作用域与全局变量
//1. 作用域:
// 全局作用域 - 整个页面都是 范围,本质上就是 指的 window对象
// 局部作用域 - 函数内部的范围
//2. 全局变量 和 局部变量
// 全局变量 : 在 全局作用域中 声明的 变量 就叫 全局变量 -- 函数外面声明的变量!!
// 特例:在函数内部 声明变量时 如果 不是使用 var关键字,那么 也是声明 全局变量!!!
// 局部变量 : 在 局部作用域中 声明的 变昂 就叫 局部变量 -- 函数内部声明的变量!!
var a = 110;
function aa() {
var b = 120;
c = 150; //全局变量: 在函数内部 声明变量时 如果 不是使用 var关键字,那么 也是声明 全局变量!!!
}
aa();
console.log(c);
console.log(window);
// 只有 函数的 {} 才有局部作用域,其他的 都是 全局作用域
//案例1 :
{
var num = 5;
}
console.log(num);//5
//案例2
var num = 5;
if (num > 3) {
var sum = 7;
}
console.log(sum); // 7
//案例3
for (var i = 0; i < 10; i++) {
}
console.log(i); // 10
//案例4 全局变量
var name = "zs";
function f() {
// 全局变量 在函数 内部 也能访问
name = "ww";
}
f();
console.log(name); // ww
//案例5 局部变量
function f() {
var name1 = "zs";
}
f();
console.log(name1); // 报错!!!
02变量的提升
//
//var num = 10;
// fun();
// function fun(){
// console.log(num);
// var num = 20;
// }
// a-----------------------------------
function fun() {
var num; // 局部变量的 声明部分 被 提到函数的 最前端
console.log(num); // undefined
num = 20;
}
var num;
num = 10; // 全局变量
fun();
// b-----------------------------------
// var a = 18;
// f1();
// function f1(){
// var b = 9;
// console.log(a);
// console.log(b);
// var a = '123';
// }
function f1() {
var a; // 局部变量的 声明部分 被 提到函数的 最前端
var b; // 局部变量的 声明部分 被 提到函数的 最前端
b = 9;
console.log(a); // undefined
console.log(b); // 9
a = '123';
}
var a;
a = 18;
f1();
// c-----------------------------------
f1();
console.log(c);//9
console.log(b);//9
console.log(a);//报错
function f1() {
var a = b = c = 9;
//var a = 9;
//b = 9;
//c = 9;
console.log(a);//9
console.log(b);//9
console.log(c);//9
}
03构造函数
//1.创建 空对象
var obj = {}; //new Object();
//2.创建 带 初始值 的对象
// var obj = {
// name: '小白',
// age: 18,
// say:function(){
// }
// };
//3.为 对象 动态添加成员(属性,方法)
obj.name = '我是新增的成员的值';
obj.age = 18;
var obj1 = {
name: '我是新增的成员的值'
};
obj1.age = 19;
console.log(obj);
console.log(obj1);
//3.写一个构造函数,用来创建 保存 图书信息 的对象
// 包含 三个属性(bookName,bookPages,bookPrice) 和 一个方法(showInfo -- 用来显示书籍的三个属性)
//【构造函数】:存在的目的 就是 为 new关键字 传入的 空对象 添加 共同 属性 和 方法
function BookInfo(bName, bPage, bPrice) {
// this 就是 new 关键字调用 本函数时 传入的 空对象
this.bookName = bName;
this.bookPages = bPage;
this.bookPrice = bPrice;
this.showInfo = function () {
console.log('我是一本书~~~');
}
}
//new 关键字: a.创建空对象 var obj = new Object(); --> var obj = { };
// b.将空对象 传给 构造函数里的 this this = obj
// c.调用构造函数
// d.返回第一步创建的对象 return obj;
var book1 = new BookInfo('进化心理学', 400, 52);
var book2 = new BookInfo('JS高级编程', 600, 73);
console.log(book1);
console.log(book2);
04关于this
// this 就是函数内部的一个特殊 属性(变量)
//1.写代码时,脑子里可以这么想: 某个对象 方法 里的 this 就是 这个对象
// 因为 要调用 一个对象里的方法时,大部分情况 都是 通过这个 对象.方法() 去调用的
//2.本质上说:对象 方法里的 this,就是 : 【谁.出这个方法,方法里的this就是谁】
/* */
//1. 声明一个 全局函数 ,可以 共享给 其他对象使用 -------------------------
var showCar = function () {
console.log('我是【' + this.pinPai + '】车~~~');
}
// 2. 两个对象 的 show 方法 共享 一个 全局函数 showCar---------------------------
var carObj1 = {
pinPai: '保时捷',
price: 2000000,
owner: 'james',
show: showCar // 将 全局函数 showCar 设置给 carObj1 的 show
};
// carObj1.show();
var carObj2 = {
pinPai: '奔驰',
price: 1000000,
owner: 'james',
show: showCar // 将 全局函数 showCar 设置给 carObj2 的 show
};
// 3. 通过 不同 对象 调用 show 方法 -----------------------------
carObj1.show(); // 此刻 方法里的 this 是 carObj1
carObj2.show(); // 此刻 方法里的 this 是 carObj1
05常见api日期对象
// api (application program interface) --> 函数 ——> 别人写好的函数
// 函数 有是那种叫法:
// a.函数 - 写在 对象外面的
// b.方法 - 写在 对象里面的
// c.api - 别人写的,我们来用
// 日期对象 Date , 数组对象 Array , 字符串 String
//1. 创建 日期对象
var dateObj = new Date();
console.log(dateObj);
//2. 格式化 日期显示
console.log(dateObj.toLocaleString());
//3. 获取 自定义的 日期格式 --------------------------------
// 2019年5月31日 9点59分59秒
function getDateTime() {
//3.1 获取年
var year = dateObj.getFullYear();
console.log(year);
//3.2 获取月份 (0-11)
var month = dateObj.getMonth() + 1;
console.log(month);
//3.3 获取天
// var day = dateObj.getDay(); // 获取星期几
var day = dateObj.getDate();
console.log(day);
//3.4 获取小时
var hour = dateObj.getHours();
console.log(hour);
//3.5 获取分钟
var minit = dateObj.getMinutes();
console.log(minit);
//3.6 获取秒钟
var second = dateObj.getSeconds();
console.log(second);
var dateStr = year + '年' + month + '月' + day + '日 ' + hour + '点' + minit + '分' + second + '秒';
return dateStr;
}
var strTime = getDateTime();
console.log(strTime);
//3.9 补充 : 获取 毫秒数 总数 --- 从 1970年1月1号 0点0分0秒 到 现在 的 总毫秒数
var allMillSeconds = dateObj.getTime().toString(); // '1559268784128'
// 将 总毫秒数 转换回 正常的 日期时间 显示
var date = changeDateFormatWithTime(allMillSeconds);
console.log(date);
function changeDateFormat(cellval) {
if (!cellval) return "暂无";
var date = new Date(parseInt(cellval.replace("/Date(", "").replace(")/", ""), 10));
var month = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;
var currentDate = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
date.get
return date.getFullYear() + "-" + month + "-" + currentDate;
}
function changeDateFormatWithTime(cellval) {
if (!cellval) return "暂无";
var date = new Date(parseInt(cellval.replace("/Date(", "").replace(")/", ""), 10));
var month = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;
var currentDate = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
var hours = date.getHours() < 10 ? "0" + (date.getHours()) : date.getHours();
var minute = date.getMinutes() < 10 ? "0" + (date.getMinutes()) : date.getMinutes();
var second = date.getSeconds() < 10 ? "0" + (date.getSeconds()) : date.getSeconds();
return date.getFullYear() + "-" + month + "-" + currentDate + " " + hours + ":" + minute + ":" + second;
}
06常见api 数组array对象
// 数组对象 -----------------------------------------------
var arrCity = ['P城', 'C城', 'Y城', 'R城', '军事基地'];
//1.concat 连接 连个数组
arrCity = arrCity.concat(['Z城','研究所']);
console.log(arrCity);
//2.join 将元素 拼接成 字符串 返回
var strCitys = arrCity.join('|'); // 传入的是 分隔符,默认 是 ,
console.log(strCitys);
console.log(strCitys.length);
//3.reverse 翻转数组 -- 直接 对 本数组 的元素做翻转操作,不需要返回值
arrCity.reverse();
console.log(arrCity);
//4.splice 删除 和 替换 --------------------------------------
var arrCity = ['P城', 'C城', 'Y城', 'R城', '军事基地'];
// 0 1 2 3 4
console.log(arrCity);
//4.1 删除 指定元素
arrCity.splice(2,1); // 从 下标2 开始删,删除 1 个元素
console.log(arrCity);
// arrCity[1] = 'G港';
//4.2 替换 指定元素
arrCity.splice(1,2,'G港'); // 从下标1删除2个元素,并替换一个 G港 到 下标1 的位置
console.log(arrCity);
var arrCity = ['P城', 'C城', 'Y城', 'R城', '军事基地'];
// 0 1 2 3 4
console.log(arrCity);
// 4.3 插入 指定元素
arrCity.splice(2,0,'Z城'); // 在 下标 为 2 的元素 前面 插入 一个元素 Z城
console.log(arrCity);
07常见api;数组对象的堆栈方法
//1.push 从尾部 添加数组元素
arrObj.push('P城');
arrObj.push('R城');
arrObj.push('Z城');
arrObj.push('Y城');
console.log(arrObj);
//2.pop 从 尾部 取出 一个 元素
var lastEle = arrObj.pop();
console.log(arrObj);
console.log('lastEle = ' + lastEle);
// ----------------------------------------------
//3.unshift 从头部 添加 一个 元素
var arrObj2 = [];
arrObj2.unshift('小猫猫');
arrObj2.unshift('小狗狗');
arrObj2.unshift('小牛牛');
console.log(arrObj2);
//4.shift 从头部 取出 一个 元素
var firstEle = arrObj2.shift();
console.log(arrObj2);
console.log('firstEle = ' + firstEle);
//5. 【栈 : 先进后出】 --- 将 一个 元素 先 存入数组,会 最后一个 取出来 ----------------------------------
// 5.1 两种栈的实现方式:从头部存,从头部取 ; 从 尾部存,从 尾部取
var arrObj3 =[];
//a.从头部存,头部取
arrObj3.unshift('a');
arrObj3.unshift('b');
arrObj3.unshift('c');
console.log(arrObj3);
console.log(arrObj3.shift());
console.log(arrObj3);
console.log(arrObj3.shift());
console.log(arrObj3);
console.log(arrObj3.shift());
console.log(arrObj3);
//5.2 【队列实现方式: 先进先出】 -- 将一个元素 先存入 数组,会 第一个 取出来
// 两种 实现方案: 从 头部存,从尾部取 ; 从 尾部存,从头部取
//a. 头部存,从尾部取
var arrObj4 = [];
arrObj4.unshift('a');
arrObj4.unshift('b');
arrObj4.unshift('c');
console.log(arrObj4);
console.log(arrObj4.pop());
console.log(arrObj4);
console.log(arrObj4.pop());
console.log(arrObj4);
console.log(arrObj4.pop());
console.log(arrObj4);
08常见api :字符串对象的api
var str = '我们都是最棒的 IT学习者~~~在前端的路上,一往无前,学无止境~~~';
//1.charAt 返回 对应 下标的 字符 -------------------------------------
var char1 = str.charAt(5);
console.log(char1);
//2.indexOf 返回 对应 字符的 下标,如果 找不到 字符,就返回 -1 ---------
// 注意:如果 有多个 相同的目标字符,返回 第一个 匹配字符的 下标
var index1 = str.indexOf('学')
console.log(index1);
//2.2 lastIndexOf 返回 对应的 最后一个 字符的下标 ---------------------
var index2 = str.lastIndexOf('学');
console.log(index2);
//2.3 找 第一个 出现的 前端 两个字的下标
var index3 = str.indexOf('');
console.log(index3);
// 思考题:如何 获取 字符串中 所有 匹配 字符的 下标呢?
// 关于 字符串 的 恒定性:字符串一旦创建,无法直接修改,只能重新创建一个新的字符串来覆盖!
//3.concat 连接字符串 -----------------------------------------------
var str = '我喜欢你,你不知道,但没关系~~~我家狗知道~~';
// str+='讨厌~~~';
str = str.concat('讨厌','死鬼','不早说~~~');
console.log(str);
//4. replace() 替换 指定的字符串 -----------------------------------
var str = '我喜欢你,你不知道,你喜欢我吗? 没关系~~~我家狗知道~~';
//4.1 默认 只能替换 第一个 匹配的 字符串
// str = str.replace('喜欢','讨厌');
//4.2 如果 要 将 所有匹配的 字符串都替换,需要使用 正则表达式
str = str.replace(/喜欢/g,'讨厌');
console.log(str);
//5.split() 将 字符串 按照 分隔符 拆成 若干个 元素,存入 数组,并返回 数组
var str = 'i love u , do u love me~~~';
var arr = str.split(' ');
console.log(arr); // ["i", "love", "u", ",", "do", "u", "love", "me~~~"]
//6.substr(index,count) 从 指定 下标 复制取出 count 个字符,并返回
var str = 'i love u , do u love me~~~';
var word = str.substr(2,4);
console.log(str);
console.log(word);
//7substring(beginIndex,endIndex) 截取范围: beginIndex <= x < endIndex
var str = 'i love u , do u love me~~~';
var word = str.substring(2,10);
console.log(word);
//8.toUpperCase() 将 字符串中 所有 英文字母 都转成 大写
var str = 'i love u , do u love me~~~';
str = str.toUpperCase();
console.log(str);
//9.toLowerCase() 将 字符串中 所有 英文字母 都转成 小写
var str = 'I LOVE U , DO U LOVE ME~~~';
str = str.toLowerCase();
console.log(str);
09常见api综合练习
//添加删除数组练习
//练习1
var arr = ["刘备"];
//添加数据后变成:["赵云","马超","刘备","关羽","张飞"]
arr.push('关羽', '张飞');
arr.unshift("赵云", "马超");
console.log(arr);
//删除数据后变成:["关羽","张飞"]
//练习2
var arr = ["赵云", "马超", "刘备", "关羽", "张飞"];
// 0 1 2 3 4 length = 5
//把数组的最后一个元素变成数组的第一个元素
//把数组的第一个元素变成数组的最后一个元素
var temp = arr[0];
arr[0] = arr[arr.length - 1];
arr[arr.length - 1] = temp;
console.log(arr);
var arr = ["赵云", "马超", "刘备", "关羽", "张飞"];
// 0 1 2 3 4 length = 5
//截取["刘备","关羽"]
// arr.splice(2,2);
//在马超后面增加 马腾
// arr.splice(2,0,'马腾');
//删除关羽
arr.splice(3, 1);
console.log(arr);
//1. 截取字符串"我爱中华人民共和国",中的"中华"
var str = '我爱中华人民共和国';
var str1 = str.substr(2, 2);
console.log(str1);
//2. "abcoefoxyozzopp"查找字符串中所有o出现的位置
// 分析:将 所有 o 的 下标 都 找到 ,并存入 数组,最后打印数组
var str = 'abcoefoxyozzopp';
// abc o ef o xy o z z o pp
// 012 3 45 6 78 9 10 11 12
var arrIndex = [];
do {
//2.1 获取 最后一个 o 的下标
var lastOIndex = str.lastIndexOf('o');
//2.2 判断 下标 是否 > -1,如果大于,说明 找到了 一个 o,如果 不大于-1,说明 已经没有o了
if (lastOIndex > -1) {
//2.3 先将 下标 存入 数组
arrIndex.push(lastOIndex);
//2.4 截取新字符串:从下标0开始截取 到 o 下标的 前一个位置
str = str.substring(0, lastOIndex);
} else {
break; //跳出循环
}
} while (true);
console.log(arrIndex);
//3. 把字符串中所有的o替换成!
var str = 'abcoefoxyozzopp';
str = str.replace(/o/g,'!');
console.log(str);
//4. 把一个字符串中所有的空格全部去掉
var str = 'i love u,but u dont know ~~~';
str = str.replace(/ /g,'');
console.log(str);
//5. 统计一个字符串中每个字符出现的次数 ----------------------
var str = 'abcoao';
//思路分析:
// a. 将所有 出现的 字符 单独保存,每种字符 只保存1次
// b. 保存 每种 字符 出现 的 次数
// { a:2 , b:1 , c:1 , o:2}
var obj = {};
for(var i = 0; i < str.length;i++){
//1.取出 字符
var charI = str[i];
//2.判断 对象中 是否 有 与 字符 同名的 属性
if( charI in obj){
//3.在 同名属性 上,累加 次数
obj[charI] += 1;
}else{
//4.如果 对象中 不存在 与 字符 同名的属性,则 动态添加一个 ,设置默认值为 1
obj[charI] = 1;
// obj.a = 1; -> obj['a'] = 1
}
}
console.log(obj);
10前自增和后自增
//前自增 : var b = ++a , 优先于 普通 算数和赋值运算符 执行,会 先 完成 ++操作,再去完成赋值
//后自增: var b = a++ , 普通算数和赋值运算符 优先于 后++,会先完成赋值,最后再去 完成++操作
// var a = 1;
// a++; // a = a + 1
// console.log(a); // 2
var a = 1;
var b = a++;
// 后++ 实际执行 如下:
// var b = a;
// a = a + 1;
console.log(b); // 1
console.log(a);
// ------------------------------------------
var a = 1;
var b = ++a;
// 前++ 实际执行 如下:
// a = a + 1;
// var b = a;
console.log(b); // 2
console.log(a); // 2
// ---------------------------------------------
var a = 1;
var b = 2;
var c = ++a + b++;
// 前++ 实际执行 如下:
// a = a + 1;
// var c = 2 + b;
// b = b + 1;
console.log(a); // 2
console.log(b); // 3
console.log(c); // 4
11引用类型和值类型
// 总结:
// 赋值: 不管是 引用类型 还是 值类型 变量 ,相互之间赋值,其实 是把 栈空间里的值 复制一份 给 另一个变量
// 传参: 不管是 引用类型 还是 值类型 传参,其实 就是 把 栈空间里的 值 复制一份 给了 形参
// 区别:值类型 栈空间 里保存 的 是 值 本身
// 引用类型 栈空间 里保存 的是 对象 的 地址
//1.简单数据类型(值类型): Number, String, Boolean, Undefined, Null
//1.1 值类型 赋值
var age = 18;
var myAge = age;
myAge++;
console.log(age); //18
//1.2 值类型 传参
function changeNum(num) {
num += 100;
}
var age1 = 100;
changeNum(age1);
console.log(age1); // 100
//
console.log('----------------------------------');
//2.复杂数据类型(引用类型):Object , Function , Array , 自定义类型(构造函数)
//1.1 引用类型 赋值
var arr = [1, 2];
var arr2 = arr;
arr2[0] = 5;
console.log(arr);
//1.2 引用类型传参
var arr5 = ['不要再讲了', '这不是扩展呀'];
function changeEle(arrObj) {
arrObj[0] = '学无止境,回头是岸';
}
changeEle(arr5);
console.log(arr5); // ['学无止境,回头是岸', '这不是扩展呀'];
</script>
12js八天的总复习
// console.log(undefined == null);
// console.log(undefined === null);
// 显示类型转换
// 1 转数值 parseInt() parseFloat() Number()
// 2 转字符串 toString() String()
// 3 转布尔值 Boolean()
// 转false:0 -0 NaN , '' , null , undefined , false ,document.all
// 转true :其他所有
// 隐式类型转换
var a = 1 + 'a'; // var a= '1' + 'a'; var a = '1a';
if (undefined) { // if( Boolean('') )
console.log('true');
} else {
console.log('false');
}
// if 结构中 ,任何一个分支条件 满足,就会 执行 分支代码,并 跳出 整个 if结构
if (1 < 2) {
}
if (1 < 2) {
} else {
}
if (1 < 2) {
} else if (2 < 5) {
console.log('我是分支代码');
} else {
}
console.log('我是结束');
//switch case 相当于 if(变量 === 值)
var age = 11;
switch (age) {
case 11: {
break;
}
case 12: {
break;
}
default: {
}
}
aaa();
//三元运算符 ? :
var gender = false;
console.log('您的性别是:' + (gender ? '男' : '女'));
function aaa() {
console.log('hi~~');
console.log('hi~~');
console.log('hi~~');
}
//调试:f11 是 逐句 调试,遇到函数,会进入到函数内部 逐句调试执行
// f10 是 逐段 调试,遇到 函数 不会进入到函数内部 逐句调试,而是直接一次性执行完函数代码,然后调试 后面的代码
//求 1-100之间 所有 能被 7 整除的数
for (var i = 1; i <= 100; i++) {
if (i % 7 == 0) {
console.log(i);
}
}
//箩筐思想 求1-100之间素有数的和 与 平均值
var luoKuang = 0;
for (var i = 1; i <= 100; i++) {
luoKuang += i;
}
console.log(luoKuang);
console.log(luoKuang / 100);
//擂台思想 求 最大值
var arr = [4, 2, 6, 81, 8, 2, 3];
var leiTai = arr[0];
for (var i = 1; i < arr.length; i++) {
if (arr[i] > leiTai) {
leiTai = arr[i];
}
}
console.log('最大值:' + leiTai);
//遍历数组
var arr = [4, 2, 6, 81, 8, 2, 3];
// length = 7
for (var i = 0; i < arr.length; i++) {
console.log(i); // 0 1 2 3 4 5 6
}
console.log(i); // 7
for (var i = arr.length - 1; i >= 0; i--) {
console.log(i); // 6 5 4 3 2 1 0
}
console.log(i); // -1
var arr1 = [12, 3, 4];
function aaaaa() {
// arguments
console.log('我是一个函数');
// return undefined;
}
console.log(aaaaa());
// 返回多个值
function sendBack() {
console.log('我要返回多个值~!!');
// return [1,2,3,];
return {
a: 1,
b: 2
};
}
//回调函数
function show(func) {
func();
}
function bb() {
}
show(bb);
// 对象的创建
var obj = {
name: '小白白'
}; // new Object();
obj.age = 19;
obj.age = 100;
delete obj.age;
// for in 遍历对象的属性名称
for(var proName in obj){
var proValue = obj[proName];
console.log(proValue);
}
14字符串的恒定性
// --------------------------- 恒定性 ---------------------------
var str = '小白';
str += ',我爱你~~'
// 一共出现了 3个字符串 的原因,就是因为 字符串恒定性:字符串 一旦创建 无法修改,只能销毁
// -------------------------------关于 值类型的 包装器 -------------------
var age = 1;
// age.toString();
// 当 我们 调用 值类型数据 的 各种方法时,js引擎 偷偷帮我们创建了 对应类型的 包装器 对象,调用的 是 包装器对象 里的方法
var age1 = new Number(1);
age1.toString()
// var a = new Array();
// 1.1 对象的字面量 表示法
var obj1 = {
name: 'james',
age: 1
};
// ----------------------------------json ---------------------------------------------------------------
var obj2 = {
'name': 'james',
'age': 1
};
// 将对象 转成 json字符串,可以 方便 网络传输,也方便 保存在本地硬盘
var jsonStr = JSON.stringify(obj1);
console.log(jsonStr);
// 将 JSON字符串 转成 对象 ,方便调用访问
var jsonObj = JSON.parse(jsonStr);
console.log(jsonObj);