1,调试
写代码--打开浏览器--F12(开发人员工具)--Sources--双击文件,在某一行代码前面点击一下(出现的东西就是断点)
例:
2.全局变量和局部变量的区别
块级作用域:一对大括号就可以看成是一块,在这块区域中定义的变量,只能在这个块中使用,但是在js中在这个块级作用域中定义的变量,外面也能使用。
说明:js没有块级作用域。
<script>
{
var num = 10;
console.log(num);//10
}
console.log(num);//10
</script>
全局变量:生命的变量是使用var声明的,那么这个变量就是全局变量,全局变量可以再页面的任何位置使用,只要是在函数外面声明的变量,都可以看成或理解成全局变量
除了函数以外,其他的任何位置定义的变量都是全局变量。全局变量,如果页面不关闭,那么久不会释放,就会占空间,消耗内存。
全局作用域:全局变量的使用范围,在任何位置都可以使用
局部变量:在函数内部定义的变量,是局部变量,外面不能使用
局部作用域:局部变量的使用范围,只能在某个地方使用--函数内
隐式全局变量:生命的变量没有var,就叫隐式全局变量
作用域链:在一个函数中使用一个变量,先在该函数中搜索这个变量,找到了则使用,找不到则继续向外面找这个变量,找到则使用,一直找到全局作用域,找不到则是undefined
全局变量是不能被删除的,隐式全局变量是可以被删除的,定义变量使用var是不会被删除的,没有var是可以删除的
3,作用域链
4,预解析:就是在执行代码之前,把变量的声明提前了,提前到当前所在的作用域的最上面,把函数的声明也会提前,提前到当前所在的所在的作用域的最上面(里面)。
预解析中,变量的提升,只会在当前的作用域中提升,提前到当前的作用域的最上面
函数中的变量只会提前到函数的作用域中的最前面,不会出去
预解析会分段(多对的script标签中函数重名,预解析的时候不会冲突)
<script>
//预解析案例
f1();
console.log(c);//9,第4个输出
console.log(b);//9,第5个输出
console.log(a);//报错,第6个输出
function f1() {
var a = b = c = 9;
console.log(a);//9,第1个输出
console.log(b);//9,第2个输出
console.log(c);//9,第3个输出
}
//分析,为什么上面的输出a会报错
//预解析的代码顺序是这样的
function f1() {
var a;//局部变量
a = 9;
//隐式全局变量
b = 9;
c = 9;
console.log(a);
console.log(b);
console.log(c);
}
f1();
console.log(c);
console.log(b);
console.log(a);
</script>
预解析小例子:
<script>
f1();
var f1 = function () {
console.log(a);
var a = 10;
}
//执行会报错,因为f1是变量,被赋值为一个函数,
// 但是预解析的时候,变量的声明会先被解析,就变成了如下
var f1;
f1();
f1 = function () {
console.log(a);
var a = 10;
}
</script>
5, arguments:可以获取函数调用的时候,传入的实参的个数,它是一个对象,一个伪数组
arguments.length是实参的个数,arguments[索引],是实参的值
<script>
//获取的是函数在调用的时候,传入了几个参数,
// 使用arguments对象,可以获取传入的每个参数的值
function f1() {
console.log(arguments.length);
}
f1(10, 20, 30);
//输出的结果是:3
</script>
<script>
function f1() {
//arguments 作为数组使用,伪数组
var sum = 0;
for (var i = 0; i < arguments.length; i++) {
sum += arguments[i];
}
return sum;
}
console.log(f1(10, 20, 30));
</script>
6,创建对象
方法一:调用系统的构造函数创建对象
var 变量名=new Object(); Object是系统的构造函数
方法二:自定义构造函数创建对象(结合第一种和需求通过工厂模式创建对象)
方法三:字面量的方式创建对象
7,json学习
json的数据实际上就是格式化后的一组字符串的数据,为了方便传值。
<script>
var json = {
"name": "小明",
"age": "20",
"sex": "男"
};
//遍历对象,是不能通过for循环遍历,无序
//可以通过for-in循环
//key是一个变量,这个变量中存储的是该对象的所有的属性的名字
for (var key in json) {
// console.log(key);//json对象中的属性的名字
// console.log(json[key]);
console.log(key + "--" + json[key]);
}
//对象中确实有这个属性对象.属性名字,或者对象[属性名字]
</script>
输出结果:
<script>
//下面的也算是json的数据,只是没有加双引号,是json格式的对象
var obj = {
name: "小苏",
age: 20,
sex: "男",
height: 198,
weight: 55
};
//遍历对象
for (var key in obj) {
console.log(key + "--" + obj[key]);
}
</script>
8, 数据类型
原始数据类型:number,string,boolean,undefined,null,object
基本类型(简单类型),值类型:Number,string,boolean
复杂类型(引用类型):object
空类型:undefined,null
值类型的值在栈中存储,引用类型的值在栈和堆中存储,对象在堆上存储,地址在栈上存储
var num=10;//值类型,值在栈上
var obj={};//复杂类型,对象在堆,地址(引用)在栈
值类型之间传递,传递的是值;引用类型之间传递,传递的是地址(引用)
值类型作为函数的参数,传递的是值;引用类型作为函数的参数,传递的是地址
例子一:
<script>
var obj={
name:"小明"
};
function f2(obj2){
obj2.name="小红";
}
console.log(obj.name);//小明
f2(obj);
console.log(obj.name);//小红
</script>
例子二:
<script>
var num1 = 55;
var num2 = 66;
function f1(num, num1) {
num = 100;
num1 = 100;
num2 = 100;//隐式全局变量
console.log(num);//100
console.log(num1);//100
console.log(num2);//100
}
f1(num1, num2);
console.log(num1);//55
console.log(num2);//100
console.log(num);//报错
</script>
例子三:
<script>
function Person(name, age, salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
function f1(person) {
person.name = "ls";
person = new Per son("aa", 18, 10);
}
var p = new Person("zs", 18, 1000);
console.log(p.name);//zs
f1(p);
console.log(p.name);//ls
</script>
9,JS中的对象:MDN--在线的手册
1》内置对象--js系统自带的对象
2》自定义对象--自己定义的构造函数创建的对象
3》浏览器对象--
*内置对象:Math,Date,String,Array,Object
#实例对象:通过构造函数创建出来,实例化的对象。实例方法必须通过实例对象调用。
#静态对象:不需要创建,直接就是一个对象,方法(静态方法)直接通过这个对象名字使用。静态方法必须通过大写的对象调用
Math:是一个内置对象,它具有数学常数和函数的属性和方法,不是一个函数对象
Math的常用方法:
<script>
var dt = new Date();
//不支持HTML5的浏览器,可以用下面这种方式
//var now=+new Date();//调用Date对象的valueOf()
dt.getFullYear();//年
dt.getMonth();//月--从0开始
dt.getDate();//日
dt.getHours();//小时
dt.getMinutes();//分钟
dt.getSeconds();//秒
dt.getDay();//星期--从0开始
dt.toDateString();//日期--英文
dt.toLocaleDateString();//日期--数字
dt.toTimeString();//时间
dt.toLocaleTimeString();//时间
dt.valueOf();//毫秒
</script>
格式化后的制定格式的日期和时间--封装成一个函数:
<script>
//格式化后的制定格式的日期和时间--封装成一个函数
/**
*获取指定格式的时间
* @param dt 日期的对象
* @returns {string} 返回的事字符串的日期时间
*/
function getDate() {
var dt = new Date();//创建日期的对象
//获取年
var year = dt.getFullYear();
//获取月
var month = dt.getMonth() + 1;
//获取日
var day = dt.getDay();
//获取小时
var hour = dt.getHours();
//获取分钟
var minute = dt.getMinutes();
//获取秒
var second = dt.getSeconds();
month = month < 10 ? "0" + month : month;
day = day < 10 ? "0" + day : day;
hour = hour < 10 ? "0" + hour : hour;
minute = minute < 10 ? "0" + minute : minute;
second = second < 10 ? "0" + second : second;
return year + "年" + month + "月" + day + "日" + hour + ":" + minute + ":" + second;
}
console.log(getDate(new Date));
</script>
10.String字符串的常用属性:
.length--->字符串的长度
.charAt(索引),返回值是指定索引位置的字符串,超出索引,结果是空字符串
.fromCharCode:(数字值,可以使多个参数),返回的是ASCII码对应的值
.concat(字符串1,字符串2,...),返回的是拼接之后的新的字符串。
.indexOf(要找的字符串,从某个位置开始的索引),返回的是这个字符串的索引值,没找到则返回-1。
.lastIndexOf:要找的字符串,从后向前找,但是索引依然是从前往后的。
.replace(“原来的字符串”,“新的字符串”),用来替换原来的字符串。
.slice(开始的索引,结束的索引),从索引为5的位置开始提取,到索引为10的前一个结束,没有10,并返回这个提取后的字符串。
.split(“要去掉的字符串”,“切割后留下的个数”),切割字符串
.substr(开始的位置,个数),返回的是截取后的显得字符串。
.substring(开始的索引,结束的索引),返回的是截取后的字符串,不包括结束的索引。
.toLowerCase()转小写
.toLocaleUpperCase()转大写
.toUpperCase()转大写
.trim()切掉字符串两端的空格
案例1:截取“杨哥”这个字符串
<script>
var str = "我爱最帅的杨哥,太帅了";
//console.log("杨哥");
var key = "杨哥";
//先获取要截取的字符串的索引的位置
var index = str.indexOf(key);
//从指定的位置开始截取,截取两个即可
str = str.substr(index, 2);
console.log(str);
</script>
案例2:找到这个字符串中所有的“o”出现的位置
<script>
var str2 = "hello wod odd ott fbo nhyo";
var index = 0;//要开始的位置
var key = "o";//要找的字符串
while ((index = str2.indexOf(key, index)) != -1) {
//如果是-1,说明找完了
console.log(index);
index += key.length;//有可能关键字为“您好”这种长度为2的,就从+2的位置开始找。
}
//4 7 10 14 20 25
</script>
案例3:找到这个字符串中每个字符出现的次数
<script>
//找到这个字符串中每个字符出现的次数
var str3="whatOareYyouYnoYshaHleiHmyHgod";
// 一,先把字符串统一大小写,这里都变成小写
str3=str3.toLocaleLowerCase();
//二,创建一个空对象,目的是把字母作为键,次数作为值
var obj={};
//三,遍历字符串,获取每个字母
for(var i=0;i<str3.length;i++){
//判断obj这个对象中有没有这个字母(字母--键)
var key=str3[i];//每个字母
if(obj[key]){//判断obj中有没有这个键
//对象中有这个字母了
obj[key]++;
}else{
//对象中没有这个字母,那就把字母加到对象中,并且给这个字母一个出现的次数,默认为1次
obj[key]=1;
}
}
//遍历对象,显示每个字母的次数
for(var key in obj){
console.log(key+"这个字母出现了"+obj[key]+"次");
}
//创建新的对象--空对象--没有属性,也没有方法
//
</script>
输出结果:
11.判断当前对象是不是数组
*Array.isArray(对象)--->判断这个对象是不是数组
*instanceof关键字
*.concat(数组,数组,数组)可以拼接多个数组
*.every(函数)--返回值是布尔类型,函数作为参数使用,函数中有三个参数,第一个参数是元素的值,第二个参数是索引值, 第三个参数是原来的数组(没用),如果这个数组中的每个元素的值都符合条件,最后才返回的是true。
*callback,回调函数,被调用时传入三个参数:元素的值,元素的索引,被遍历的数组。
*.filter(函数),返回的是数组中每一个元素都符合条件的元素。
*.push(值),把值追加到数组中,加到最后了,返回值是追加数据之后的数组的长度。
.pop(),删除数组中最后一个元素,返回值就是删除的这个值。。
.shift(),删除数组中第一个元素,返回值就是删除的这个值。
.unshift(),向数组的第一个元素前面插入一个新的元素,返回值是插入后的长度。
.forEach(函数)方法--遍历数组用--相当于for循环
.indexOf(元素值),返回的是索引,没有则是-1
.join(字符串),返回的是一个字符串
.map(函数),数组中的每个元素都要执行这个函数,把执行后的结果重新的全部放在一个新的数组中
.reverse()---反转数组
.sort()---排序的,可能不稳定,如果不稳定,请写MDN中的那个固定的代码
arr.slice(开始的索引,结束的索引),把截取的数组的值放在一个新的数组中,但是不包含结束的索引对应的值
.splice(开始的位置,要删除的个数,替换的元素的值);一般是用于删除数组中的元素,或者是插入的元素
12,基本包装类型
#普通变量不能直接调用属性或者方法
#对象可以直接调用属性和方法
#基本包装类型:本身是基本类型,但是在执行代码的过程中,如果这种类型的变量调用了属性或者是方法,那么这种类型就不再是基本类型了,而是基本包装类型,这个变量也不再是普通的变量了,而是基本包装类型对象
例1:
var num=10;//number---数字类型
console.log(num.toString());//--num现在是对象,变成基本包装类型
输出:10
例2:
var flag=new Boolean(false);
var result-flag&&true;
console.log(result);
例3:
var num=10; //基本类型
var num2=Number("10"); // 基本类型,转换,没有new,类型转换
var num3=new Number("10"); //基本包装类型
输出:true---因为flag原来是变量,但是new之后是对象了,不管后面是true还是false,只要是对象&&true,结果就是后面的。
注:如果是一个对象&&true,那么结果是true;如果是一个true&&对象,那么结果是对象