JavaScript课程——Day04(循环、函数声明及调用、函数的参数、作用域及域解析、函数返回值、代码复用)
1、循环
1.1、json对象
var 变量名 = { key1: value1, key2: value2, ... }
var obj = { 'name': 'zs', 'age': 3, 'job': '前端开发' } // console.log(obj);
读取和修改
// 读取(点的方式): 对象.属性 console.log(obj.name); console.log(obj.age); // 读取(中括号的方式):对象['属性'] console.log(obj['job']); // 中括号优势,可以读取属性是变量的 var a = 'name'; console.log(obj[a]); // ------------------------------ // 修改: 对象.属性 = 值; obj.name = '张新昊'; obj.sex = '女'; obj['sex'] = '不明'; console.log(obj);
1.2、for-in
for-in:循环对象,因为对象没有length属性,所以不能用for循环,只能用for-in
for (var 属性 in 对象) { console.log(属性 即key值); console.log(对象[属性] 即value值); }
var obj = { 'name': 'zs', 'age': 3, 'job': '前端开发' } for (var attr in obj) { console.log(attr, '------', obj[attr]); }
2、函数声明及调用
函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块
语法:
// 1、函数声明 function 函数名(形参1, 形参2, ...) { 代码块 } // 2、函数表达式 var 函数名 = function (形参1, 形参2, ...) { 代码块 } // 函数调用:函数名(实参1, 实参2, ...);
// x y为形参(形式上的参数) function add(x, y) { console.log(x + y); } // 10,20为实参(实际的参数) add(10, 20); add(50, 100); // --------------------------------------- function fn(a) { var num = 0; for (var i = 1; i <= a; i++) { num += i; } console.log(num); } fn(100); fn(50);
3、函数的参数
形参:在声明函数时,函数中一些不确定的值,我们可以先定义一个变量表示,这个变量我们就称之为形参。每一个形参都是一个变量声明,只不过省略了var,但是这个时候的形参并没有值。
实参:在调用参数时,如果函数声明时有参数,就可以在括号中传入具体的值,这个叫做实参。
3.1、实参和形参个数不等
- 如果实参比形参少,则没有匹配上的形参值为undefined
- 如果实参比形参多,则多的实参也白多
例:
function fn(a, b) { console.log(a, b); } fn(3, 5); fn(7); // a的值为7,b为undefined fn(10, 20, 30); // a的值为10,b的值为20,实参30将丢失
3.2、arguments
arguments是实参的集合,是一个对象,一个类数组、伪数组,有长度,可以用过下标获取到某一个参数
// 需求:写一个函数,用于计算不定参数的和 function fn() { // console.log(typeof arguments); // object // console.log(arguments); // console.log(arguments[0], arguments[1]); var num = 0; for (var i = 0; i < arguments.length; i++) { // console.log(arguments[i]); num += arguments[i] } console.log(num); } fn(3, 5); fn(4, 5, 6);
3.3、arguments和形参的关系
形参和arguments是一一对应的,是一个值的两个名
function fn(x, y) { arguments[0] = 10; console.log(x); // 10 console.log(arguments[0]); // 10 } fn(3, 5);
3.4、函数参数的类型
函数的参数可以是任何类型数据,包括函数
function fn(a) { console.log(a); console.log(typeof a); console.log('------------------------'); } fn(5); //数字 numeber fn('5'); //字符串 string fn(true); //布尔 boolean fn(null); //null object fn(); //undefined undefined fn([]); // object fn({}); //对象 object fn(function () { }); //函数 function () { }
function ab(f) { f() } function add() { console.log(10 + 20); } ab(add)
4、作用域及域解析
作用域:变量或函数的有效使用范围,有全局作用域和函数作用域(局部作用域)两种
全局作用域:<script>标签下
局部作用域:函数域下
4.1、全局变量和局部变量
全局变量:声明在script标签下的标量或函数,全局变量或函数在任何地方都可以访问,任何地方都可以修改
var a = 10; function fun1() { a++; console.log(a); // 11 } function fun2() { a++; // 12 a--; // 11 console.log(a); // 11 } fun1(); fun2(); console.log(a); // 11
局部变量:在函数内部声明的变量或函数,就是局部变量。局部变量或函数只能在函数内部访问
function sum() { var a = 10; console.log(a); // 10 function s() { console.log(a); // 10 } s(); } sum(); console.log(a); s();
4.2、作用域链
JavaScript中的一种值的查找即机制,当需要使用到一个变量或函数,先查找自身作用域,自身作用域没有,再从父级作用域中找,依次查找,一直到全局,全局还是没有,显示is not defined
4.3、预解析
浏览器是个多功能的集合体,它可以运行js、css、html、图片、音视频,浏览器有一块专门用于解析js,我们称为解析器
解析器工作的原理:至少会经历两步
①、预解析
找东西,找var、函数、参数,找到之后,var附一个值为undefined提到当前域的最上面,函数整体提到当前域的最上面,参数同var
如果函数同var同名,函数权重高于var,函数抹掉var;如果var与var同名,则后面的覆盖前面的;如果函数同名,则后面的覆盖前面的
②、逐行解读
从上到下,一行一行的执行,见到+ - * / % ++ -- =等操作,就跑到前面修改变量,遇到读取,就跑到最前面读取这个变量
// console.log(a); // var a = 10; // console.log(a); // 变形 // var a = 10; // console.log(a); // undefined // a = 10; // console.log(a); // 10 // --------------分隔------------------ // console.log(fun1); // function fun1() { // console.log('fun1'); // 我是一个注释 // } // console.log(fun1); // 变形 // function fun1() { // console.log('fun1'); // 我是一个注释 // } // console.log(fun1); // console.log(fun1); // ----------------分隔---------------- // var a = 1; // function fn1() { // alert(a); // var a = 2; // } // fn1(); // alert(a); // 变形 // var a = 1; // function fn1() { // var a = 2; // alert(a); // undefined // a = 2; // // } // a = 1; // fn1(); // alert(a); // 1 // ---------------分隔----------------- // var a = 1; // function fn1() { // alert(a); // a = 2; // } // fn1(); // alert(a); // 变形 // var a = 2; // function fn1() { // alert(a); // 1 // a = 2; // } // a = 1; // fn1(); // alert(a); // 2 // --------------分隔-------------- // var a = 1; // function fn1(a) { // alert(a); // a = 2; // } // fn1(); // alert(a); // 变形 // var a = 1; // function fn1(a) { // var a = 2; // alert(a); // undefined // a = 2; // } // a = 1; // fn1(); // alert(a); // 1 // -------------分隔------------------ // var a = 1; // function fn1(a) { // alert(a); // a = 2; // } // fn1(a); // alert(a); // 变形 // var a = 1; // function fn1(a) { // var a = 2; // alert(a); // 1 // a = 2; // } // a = 1; // fn1(a); // alert(a); // 1 // ------------分隔---------------- // var a = 10; // function fun2() { // console.log(a); // undefined // var a = 20; // console.log(a); // 20 // } // fun2(); // console.log(a); // 10 // ------------分隔--------------- // alert(a); // var a = 1; // alert(a); // function a() { alert(2); } // alert(a); // var a = 3; // alert(a); // function a() { alert(4); } // alert(a); // alert(typeof a) // a(); // 变形 // a = 3; // alert(a); // function a() { alert(4); } // a = 1; // alert(a); // 1 // alert(a); // 1 // a = 3; // alert(a); // 3 // alert(a); // 3 // alert(typeof a) // number // a(); // 报错 // ----------------分隔----------------- // function fn(a) { // console.log(a); // function a() { } // var a = 2; // function a() { } // console.log(a) // 2 // } // fn(1); // -------------分隔--------------- // var a = 2; // function test() { // var a = 3; // var b = 4; // c = 5; // 没有var,声明的是一个全局变量 // alert(a); // 3 // } // test(); // alert(c); // 5 // alert(b); // 报错
5、函数返回值
return特点:
1、函数通过关键字return返回函数中的内容
2、return一次只能返回一个值(如果要返回多个值,可以返回 [ ] 或者 { } )
3、函数中只要遇到return,函数就会结束
4、函数没有返回值,默认结果为undefined
// 封装函数:工具 // 封装一个函数,求1--n之间所有数的和 function fn(n) { var num = 0; for (var i = 1; i <= n; i++) { num += i; } // console.log(num); return num; // return后面的值,就是函数调用的结果 } var v = fn(100); console.log(v); // 5050 console.log(fn(50)); // 1275 // num是一个局部变量,我们在外面找不到。(我就需要在外面得到这个值,怎么办) // console.log(num);
6、代码复用
1、html结构尽量标准一样
2、先实现一个,但是里面的标签必须通过父元素获取
3、封装成函数,将父元素作为函数参数
4、调用
购物车案例:
<h1>函数封装复用</h1> <ul> <li> <button>-</button> <span>0</span> <button>+</button> 单价:<b>12.5</b>元 小计:<em>0</em>元 </li> <li> <button>-</button> <span>0</span> <button>+</button> 单价:<b>9.8</b>元 小计:<em>0</em>元 </li> <li> <button>-</button> <span>0</span> <button>+</button> 单价:<b>2.7</b>元 小计:<em>0</em>元 </li> <li> <button>-</button> <span>0</span> <button>+</button> 单价:<b>178</b>元 小计:<em>0</em>元 </li> <li> <button>-</button> <span>0</span> <button>+</button> 单价:<b>17.8</b>元 小计:<em>0</em>元 </li> </ul> <script> // 获取元素 var li = document.getElementsByTagName('li'); // 获取所有的li // fn(li[0]); // fn(li[1]); // fn(li[2]); for (var i = 0; i < li.length; i++) { fn(li[i]); } function fn(ele) { var btn = ele.getElementsByTagName('button'); // 加减按钮 var span = ele.getElementsByTagName('span')[0]; // 件数盒子 var b = ele.getElementsByTagName('b')[0]; // 单价盒子 var em = ele.getElementsByTagName('em')[0]; // 小计盒子 var count = span.innerText - 0; // 件数 var money = b.innerText * 1; // 单价 // 减 btn[0].onclick = function () { count--; if (count <= 0) { count = 0; } span.innerText = count; em.innerText = (count * money).toFixed(2); } // 加 btn[1].onclick = function () { count++; span.innerText = count; em.innerText = (count * money).toFixed(2); } } </script>