2.2 自定义属性
.2.1 定义属性
-
属性的分类
-
固有属性:系统给的 id class title
-
自定义属性:程序员自己定义的 tag index
-
-
添加自定义属性
-
直接添加标签上(暂时获取不到)
<div tag = "true"></div> //2.自定义属性直接写行间,可以直观看见,暂时无法获取写在行间的自定义属性 console.log(oDiv.tag); //undefined
-
使用js添加:标签.属性名 = 属性值
//3.通过js添加自定义属性,标签上看不见,但是可以直接使用 oDiv.a = true; console.log(oDiv.a); //true
-
2.2.2 自定义属性使用场景
-
多组开关效果(自定义属性)
-
自定义索引
-
问题:通过for循环添加事件,想在事件里面使用i下标值,但是拿到的i值永远是最后一次的值
-
解决:通过自定义属性 在绑定事件之前就将i值定义到标签的属性上
<body> <button >首页</button> <button >同步课程</button> <button >课程详情</button> <div style="display:block">首页的内容</div> <div>同步课程的内容</div> <div>课程详情的内容</div> <script> /* 点击第一个button 显示第一个div 点击第二个button 显示第二个div 点击第三个button 显示第三个div */ var btn = document.getElementsByTagName("button"); var odiv = document.getElementsByTagName("div"); //给btn点击点击事件 for(var i = 0;i<btn.length;i++){ console.log(i);// 0 1 2 btn[i].index = i;//自定义索引 btn[i].onclick = function(){ //如果是for循环添加事件 是无法拿到i的值 可以通过自定义属性 将i值定义到标签上 // console.log(i);//3 //先清空所有的样式 for(var j = 0;j<odiv.length;j++){ odiv[j].style.display = "none"; } //标签.index 获取自定义属性 console.log(this.index) odiv[this.index].style.display = "block"; } } </script> </body>
-
3.函数
3.1 概念
-
函数(function):函数就是将具有独立功能的代码块 整合在一起并命名 需要的时候调用即可
-
好处:提高代码的复用率
左箭头.onclick = function(){ change } 右箭头.onclick = function(){ change } 指示点.onclick = function(){ change} //切换图片 function change(){ 切换图片 }
-
函数使用场景
-
事件处理函数
标签.事件类型 = function(){}
-
代码复用封装
左箭头.onclick = function(){ change } 右箭头.onclick = function(){ change } 指示点.onclick = function(){ change} //切换图片 function change(){ 切换图片 }
-
对象的方法
var obj = { "name":"张三", "age":10, "isOn":true "a":undefined, "b":null, "c":[1,2,3,4], "d":{}, "f":function(){ } 函数在对象中叫方法 } //获取对象中的属性 obj.属性名 //调用对象中的方法 obj.对象名() obj.f()
-
3.2 函数声明及使用
-
代码复用封装的声明
-
普通声明
-
表达式声明
-
-
普通声明和使用
声明:function 函数名(){ 代码块 } 使用:函数名()
-
表达式声明和使用
声明 var 变量名 = function(){ 代码块 } 使用 变量名()
-
声明和使用代码示例
<script> // 1.普通声明 function change(){ console.log("切换图片") } // 函数只有调用的时候 才会执行里面的代码 调用一定要在函数名后面加() change();//切换图片 // 在打印的时候 如果只写函数名 将整个函数打印输出 console.log(change) // “function change(){ console.log("切换图片") }" // 2.表达式声明 var change1 = function(){ console.log("切换图片1"); } // 使用 change1();//"切换图片1" console.log(change1);// "function(){console.log("切换图片1")}" </script>
==函数使用注意==
-
函数只有调用的时候 才会执行里面的代码 调用一定要在函数名后面加()
-
在打印的时候 如果只写函数名 将整个函数作为字符串打印输出
3.3 函数参数
-
什么需要参数:函数中出现不确定的值,传递不同的参数 实现不同的功能
-
参数的分类
-
形参(形式参数):function 函数名(a,b){ }------a和b就是形参
-
实参(实际参数):函数名(100,200)-----100和200就是实参 实参是将值赋值给形参
-
-
当形参和实参的个数不匹配的时候
-
==形参和实参是一一对应的==
-
//4.当形参和实参个数不对应的时候 function add3(a,b){//var a; var b; console.log(a,b); console.log(arguments);//参数的集合 arguments[0] = 100;//arrguments[0] 和 a是一样的 修改arrgument[0]的值 a也会跟着改变 console.log(a);// 100 } // add3(10);//10 undefined 实参比形参个数少 // add3(10,20,30);//10,20 实参比形参个数多 add3(10,20);//10,20 实参和形参个数相同
-
多个参数: 多个参数之间用逗号隔开
<script> // 1.普通的声明 两个值相加 function add(a, b) {// var a; a=100 var b; b=200 // console.log(a,b); console.log(a + b); } //使用 10/20 20/30 40/100 200/300 add(100, 200); add(10, 20); // 30 add(20, 30);// 50 add(40, 100);// 140 add(200, 300)// 500 //2.表达式声明 var add1 = function(a,b){//var a; var b; console.log(a*b); } add1(10,20);//200 </script>
-
参数不确定 arguments参数的集合
//3.当参数个数不确定的时候:arguments参数集合 你传几个值 我就累加几个值 function add2(){ // console.log(arguments);//实参的集合 console.log(arguments.length);//实参的集合的长度 console.log(arguments[0])//10 arguments[下标] 获取下标对应的参数 var s = 0// for(var i = 0;i<arguments.length;i++){ s+=arguments[i] } console.log(s); } add2(10,20,40);//3个参数 add2(10,20,30,40,50);// 5个参数 add2(100,200);//2个参数
-
==函数的注意问题==
-
函数名重名会被覆盖
-
实参比形参少,没有被赋值的形参值为undefined
-
function add(){ console.log("快吃饭了") } function add(){ console.log("中午吃什么") } add();// 中午吃什么 function add1(a,b){ console.log(a,b); } add1(10);//10 undefined
4.作用域
-
作用域:变量或者函数的有效使用范围
-
作用域分类:局部作用域 全局作用域
-
全局变量/函数 局部变量/函数
-
全局变量/函数:在函数外声明变量/函数,可以在代码中的任何地方访问和修改,会一直存储在计算机的内存中,直到页面关闭
-
局部变量/函数:在函数内部声明的变量/函数,只能在函数内部使用 出了函数就会被销毁
-
var a = 10; function fn1(){ var x = 10; var y = 20; console.log(x,y); function fn2(){ console.log("这是函数2") } } fn1(); //全局变量和函数 a全局变量 fn1全局函数 x y是局部变量 fn2是局部函数
4.1 全局变量
-
在函数外声明变量/函数,可以在代码中的任何地方访问和修改,会一直存储在计算机的内存中,直到页面关闭
/* 全局变量/函数 :在函数外声明变量/函数,可以在代码中的任何地方访问和修改,会一直存储在计算机的内存中,直到页面关闭 */ var a = "我是变量a"; function fn1(){ console.log(a);//"我是变量a" a = "我改变了a"; var x = 10; var y = 20; console.log(x,y); function fn2(){ console.log(a);//"我是变量a" console.log("这是函数2") } } fn1(); console.log(a);//"我改变了" //全局变量和函数 a全局变量 fn1全局函数 x y是局部变量 fn2是局部函数
4.2 局部变量
-
在函数内部声明的变量/函数,只能在函数内部使用 出了函数就会被销毁
<script> /* 全局变量/函数 :在函数外声明变量/函数,可以在代码中的任何地方访问和修改,会一直存储在计算机的内存中,直到页面关闭 */ var a = "我是变量a"; function fn1(){ console.log(a);//"我是变量a" a = "我改变了a"; var x = 10; var y = 20; console.log(x,y);// 10 20 function fn2(){ console.log(a);//"我是变量a" // console.log("这是函数2"); } fn2(); } fn1(); console.log(a);//"我改变了" // console.log(x,y);// x is not defind y is not defind fn2();//n2 is not defined //全局变量和函数 a全局变量 fn1全局函数 x y是局部变量 fn2是局部函数 </script> <script> var a = "10"; b = 30;// 声明变量不带var 相当于声明全局变量 function fn1() { var x = 20; function fn2() { console.log("你中午吃啥") } console.log(x);//20 } console.log(b);//30 console.log(a);//"10" // console.log(x);// x is not defined // fn2();//fn2 is not defined fn1(); </script>
-
==注意==
-
声明变量不带var 也可以使用 但是声明出来是全局变量
-
只要是在函数内部声明的东西 都是局部变量
-
4.3 作用域链
-
作用域链:是js的一种查找机制,先找自身作用域范围内,再依次往父级作用域查找,直到找到全局变量 如果全局变量范围也找不到 就是is not defined
<script> // 是js的一种查找机制,先找自身作用域范围内,再依次往父级作用域查找,直到找到全局变量 如果全局变量范围也找不到 就是is not defined //1. var x = 10; function fn1() { var x = 20; b = 20;//全局变量 因为没有带var console.log(x);//20 } fn1(); console.log(b);//20 //2 var y = 100; function fn2() { console.log(y);//100 } fn2(); //3 function fn3() { // console.log(a);//a is not defined } fn3(); //4 function outer() { function inner() { console.log("我是内部的inner") } inner();//我是内部的inner } outer(); // inner();// inner is not defined </script>
-
作用域链练习
//练习1: var a = 10; function fun() { var b = 20; console.log(a, b);// 10 20 a = 30; //修改的是全局变量a a = 30 b = 40; // 修改的是局部量b b = 40 c = 50; // 全局变量c c=50 } fun(); console.log(c);// 50 console.log(a);// 30 console.log(b);// b is not defined //练习题2: var x = 0; var y = 10; function fun2() { var x = 20; console.log(x, y);// 20 10 x = 30;//修改是局部变量x x = 30 } fun2(); console.log(x, y);// 0 10 //练习3: var n = 10; var m = 100; function fun3() { var m = 20; console.log(n, m);// 10 20 n = 40;//修改的是全局变量n n = 40 } fun3(); console.log(n, m);// 40 100
4.4 预解析
-
分析
<script> console.log(a);//undefined var a;声明变量没有赋值 var a = 10; console.log(a);//10 fn1();//"ahahahha" function fn1(){ console.log("ahahahha"); } fn1();// "ahahahha" </script>
-
通过以上代码,代码不是单纯的从上往下执行 计算机在解析的时候 从上往下执行会经过很多步骤 ,至少掌握住两种步骤
-
1.预解析(变量提升)
-
找var关键字 提前声明变量(只看等号左边的内容),如果变量重名 在内存中 只会声明一次
-
找function关键字 提前声明整个函数 如果重名会多次声明
-
-
2.逐行执行
-
逐行执行的时候 会忽略funtion函数声明 和var 变量声明
-
// 2. var a = 10; var a = 20; //只在内存中存储一次 var a console.log(a);//20 function fn1(){ console.log("吃饭睡觉打豆豆") } function fn1(){ console.log("为什么要打豆豆") } //两个fn1都内存中存储了 但是在内存中 也会出现同名会被覆盖 fn1();
-
-
预解析练习
==变量和函数重名也会被覆盖==
<script> //练习1 console.log(f1);// "function f1(){console.log("函数2")}" function f1() { console.log("函数1") } console.log(f1);// "function f1(){console.log("函数2")}" function f1() { console.log("函数2") } console.log(f1);// "function f1(){console.log("函数2")}" //练习2 变量和函数重名也会被覆盖 console.log(c);//"function c(){console.log('函数2')}" var c = 10; function c(){ console.log("函数1") } console.log(c);// 10 var c = 20; function c(){ console.log("函数2") } console.log(c);//20 var c = 30; console.log(c);// 20 //练习3 var a = 10; function a(){ console.log("函数3") } a();// a is not funtion </script>
-
预解析练习
//练习4.普通函数声明与表达式声明的区别 普通函数可以提前调用 表达式声明无法提前调用 // 普通声明 fn1();//"普通声明" function fn1(){ console.log("普通声明") } //表达式声明 fn2();//undefined(); fn2 is not funtion var fn2 = function(){ console.log("表达式声明") } //练习5 console.log(c);// "function c(){console.log('函数2')}" var c = 10; function c(){ console.log("函数1"); } console.log(c);// 10 var c = 20; function c(){ console.log("函数2"); } console.log(c); // 20 // c(); // 报错 c is not funtion //练习6:局部作用域的域解析 function sum(){ console.log(a);//undefined var a = 10; } sum(); //练习7 var x = 10; function fun1(){ console.log(x);// undefined 查找机制 先找自己内部的 找不到再父级作用域 var x = 20; } fun1(); //练习8 function fun2(a){ //var a; a=100 console.log(a);// 100 var a = 20; console.log(a);// 20 } fun2(100);
-
预解析练习
//01 console.log(a);// a is not defined a = 0; // //02 console.log(a);// undefined var a = 0; console.log(a);// 0 //03 console.log(a);//"function a(){console.log('我是函数')}" var a = '我是变量'; function a() { console.log('我是函数') } console.log(a);// "我是变量" // //04 console.log(a);//"function a(){console.log('我是函数')}" a++;// a=a+1 console.log(a);// NaN var a = '我是变量'; function a() { console.log('我是函数') } console.log(a);// "我是变量" // //05 console.log(a);//全局变量 undefined var a = 0; console.log(a); //全局变量 0 function fn() { console.log(a);//局部变量a undefined var a = 1; console.log(a);// 局部变量a 1 } fn() console.log(a);//全局变量 0
4.5函数返回值
-
什么时候需要函数返回值
-
函数外侧需要函数内部的值
-
-
语法: return 返回值
//1.return 返回值的基础用法 function add(a,b){ var s = a+b; console.log(s);// 300 return s;//将结果返出去 } //在外侧获取到300 // console.log(s);// s is not defined var res = add(100,200);// 调用并接受返回值 console.log(res);// 300
-
==注意事项==
-
注意1:return一次只能返回一个值 如果连续写多个 返回的是最后一个值
-
注意2: return不仅有返回值的作用 还有结束函数执行的作用(遇到return就结束)
-
//注意1 return一次只能返回一个值 如果连续写多个 返回的是最后一个值 function fn1(a, b) { var sum1 = a + b; var sum2 = a - b; // return sum1,sum2; //如果想一次返回多个数据 可以返回一个数组或者object类型 // return [sum1,sum2]; return { "he":sum1, "cha":sum2 } } var a = fn1(100, 200); console.log(a);// [300, -100] {"he":300,'cha';-100} // 注意2: return不仅有返回值的作用 还有结束函数执行的作用(遇到return就结束) function fn2(a,b){ var sum1 = a*b; var sum2 = a/b; return [sum1,sum2]; // console.log("你说我还会执行吗?") //函数中不能写两个return 因为遇到第一个return的时候 就已经返回并结束函数 // return sum1; // return sum2; } var c = fn2(200,50); console.log(c);// [10000,4]