1. 数组

1.1 init

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><!-- 两种方式创建数组:1. new Array();     (对象)2. [1,2,3,4...];    (字面量)--><script>var array = [1, 2, 'fs', true];    //可以存放任意类型的数据console.log(array);console.log(array[2]);array.length = 8;               //手动修改数组长度console.log(array);var Array = [1,1,3];Array[3] = 4;                   //增加了一个元素console.log(Array);Array = "Hello World!";         //将原来Array中的元素给全部覆盖了console.log(Array);</script>
</head>
<body></body>
</html>

1.2 数组

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script>// var arr = [1,2,3];var arr = new Array();var arr1 = new Array(2);    //长度为2,为empty*2var arr2 = new Array(2, 3);  //分别是2,3console.log(arr1);console.log(arr2);//检测是否为数组console.log(arr1 instanceof Array); //way1console.log(Array.isArray(arr2));   //way2//arr.push('hello');  //尾插arr.unshift(1);     //头插console.log(arr);arr.pop();          //尾删arr.shift();        //头删console.log(arr);//var Arr1 = ['pink', 'red', 'green'];Arr1.reverse();console.log(Arr1);var Arr2 = [13, 4, 77, 1, 7];// Arr2.sort(); //并不是想象中的排序// console.log(Arr2); // 如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,// 说得更精确点,是按照字符编码的顺序进行排序。要实现这一点,// 首先应把数组的元素都转换成字符串(如有必要),以便进行比较。var arr = new Array(6)arr[0] = "George"arr[1] = "John"arr[2] = "Thomas"arr[3] = "James"arr[4] = "Adrew"arr[5] = "Martin"document.write(arr + "<br />")document.write(arr.sort())//// 请注意,上面的代码没有按照数值的大小对数字进行排序,要实现这一点,就必须使用一个排序函数Arr2.sort(function (a, b) {return a - b;  //升序// return b - a;   //降序});console.log(Arr2);//indexof(),lastindexof()//toString()var ARR = [1, 2, 3];console.log(ARR);               //[1,2,3]console.log(ARR.toString());    //1,2,3 ---字符串console.log(ARR.join('#'));     //1#2#3 ---字符串</script>
</head><body></body></html>

2. 函数

2.1 函数

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><!-- 函数的定义:1. 命名函数; 2. 匿名函数; 3. new Function('arg1', 'arg2', 'arg3'); ( 里面的参数必须都是字符串格式 ) ( 不太常用 )4. 所有函数都是Function的实例对象; 5. 函数也属于对象; (add instanceof Object)--><script>//1. 命名函数**********************************************************function sum() {var sum = 0;for (var i = 0; i <= 100; i++) {sum += i;}console.log(sum);}sum();//2. 函数表达式(匿名函数)*************************************************var NUM = function (num) {console.log('functioal expression!');console.log(num);}NUM(111);//3. new Function() ****************************************************var f = new Function('a', 'b', 'console.log(a + b)');f(999, 1000);console.log(f instanceof Object);  // true//3. 带参函数************************************************************function add(a, b) {console.log(a + b);}add(1, 2); //3add(1, 2, 3); //3(多余的参数直接被忽略)add(1); //NaN//4. 函数返回************************************************************//(1)eg1function sub(num1, num2) {return num1 - num2;}console.log(sub(3, 5));//(2)eg2function getArrayMax(arr) {var max = 0;for (var i = 0; i < arr.length; i++) {if (arr[i] > max) {max = arr[i];}}return max;}console.log(getArrayMax([2, 4, 1, 5, 2, 6, 4]));//(3)eg3function result(num1, num2) {return [num1 + num2, num1 - num2, num1 * num2];}console.log(result(1, 4));//5. 嵌套调用************************************************************function out() {console.log('i am out!');In();}out();function In() {console.log('i am in!');}//6. other function test() {}console.log(test()); // test()没有return, 则返回undefined</script>
</head><body>
</body></html>

2.2 arguments伪数组

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script>/*1. 当我们不确定有多少个参数传递的时候,可以用arguments对象来获取; 在JS中,arguments实际上它是当前函数的一个内置对象; [所有函数都内置了一个arguments对象,arguments对象中存储了传递的所有实参!]arguments对象的展示形式是一个[伪数组],因此可以进行遍历;2. 作用:有了arguments就不用在函数中写形参了; 3. 伪数组具有以下特性:1. 具有length属性; 2. 按索引方式存储数据; 3. 不具有数组的push,pop等方法; 4. (1) 正常模式下,arguments对象可以在运行时修改; (2) 严格模式下,arguments对象是一个只读对象,修改它是无效的,但不会报错; */function fun() {console.log(arguments);console.log(arguments.length);console.log(arguments[1]);for(var i =0 ;i < arguments.length;i++) {console.log(arguments[i]);}}fun(1,2,3,4,5);/**************************************************************************/function max() {var max = arguments[0];for(var i = 0;i < arguments.length;i++) {if(arguments[i] > max) {max = arguments[i];}}return max;}console.log(max(1,2,3));console.log(max(1,2,3,4,5));console.log(max(11,21,63,98,21,12));</script>
</head>
<body></body>
</html>

2.3 函数的调用方式

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><!-- 函数的调用方式:1. 普通函数的调用; 2. 对象的方法的调用; 3. 构造函数; 4. 事件绑定函数; 5. 定时器函数; 6. 立即执行函数; -->
</head><body><script>// 1. 普通函数function fn() {console.log('人生的巅峰');}fn();   fn.call(); // 2. 对象的方法var o = {sayHi: function() {console.log('人生的巅峰');}}o.sayHi();// 3. 构造函数function Star() {};new Star();// 4. 绑定事件函数// btn.onclick = function() {};   // 点击了按钮就可以调用这个函数// 5. 定时器函数// setInterval(function() {}, 1000);  这个函数是定时器自动1秒钟调用一次// 6. 立即执行函数: 自动调用(function() {console.log('人生的巅峰');})();</script>
</body></html>

2.4 函数中的this指向问题

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><!-- 函数中的this指向问题:1. 普通函数的调用;      this指向window; 2. 对象的方法的调用;    this指向对象;3. 构造函数;            this指向实例对象; 4. 事件绑定函数;        this指向调用者, 比如按钮; 5. 定时器函数;          this指向window; 6. 立即执行函数;        this指向window; -->
</head><body><script>// 1. 普通函数function fn() {console.log('人生的巅峰');}fn();   fn.call()// 2. 对象的方法var o = {sayHi: function() {console.log('人生的巅峰');}}o.sayHi();// 3. 构造函数function Star() {};new Star();// 4. 绑定事件函数// btn.onclick = function() {};  // 5. 定时器函数// setInterval(function() {}, 1000);  // 6. 立即执行函数: 自动调用(function() {console.log('人生的巅峰');})();</script>
</body></html>

2.5 高阶函数

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><!-- 高阶函数:是对其他函数进行操作的函数, 它接收函数作为参数 或 将函数作为返回值输出; -->
</head>
<body><script>// 1. 函数作为参数进行传递function fun(a, b, callback) {console.log(a + b);callback && callback();}fun(1, 2, function () {  console.log('last call!');}); </script><script>// 2. 返回函数function Fun() {return function(a, b) {console.log(a - b);}}var _f = Fun();_f(1, 3);</script>
</body>
</html>

2.6 值址传递

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><script>/*1. 值传递: 函数参数如果是原始类型的值(数值、字符串、布尔值),传递方式是```值传递```; ```这意味着,在函数体内修改参数值,不会影响到函数外部```; var num = 2;function f(_num) {_num = 3;}f(num);console.log(num);  // 2*//*2. 址传递:但是,如果函数参数是复合类型的值(```数组、对象、其他函数````),传递方式是```传址传递```; 也就是说,传入函数的是原始值的地址,因此在函数内部修改参数,将会影响到原始值; var obj = {num: 1};function fff(o) {o.num = 222;}fff(obj);console.log(obj);   // {num: 222}*//*3. 注意,如果函数内部修改的,不是参数对象的某个属性,而是替换掉整个参数,这时不会影响到原始值; 下面代码中,在函数test内部,参数对象obb被整个替换成另一个值, 这时不会影响到原始值; 这是因为,形式参数(o)的值实际是参数obb的地址; 重新对o赋值导致o指向另一个地址,保存在原地址上的值当然不受影响; */var obb = [1, 2, 3];function test(o) {o = [4, 5, 6];}test(obb);console.log(obb);   // [1,2,3]</script>
</body></html>

2.7 改变this指向的三个方法

(1)call()方法

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><!-- this的动态切换,固然为 JavaScript 创造了巨大的灵活性,但也使得编程变得困难和模糊。有时,需要把this固定下来,避免出现意想不到的情况。JavaScript 提供了call、apply、bind这三个方法,来切换/固定this的指向。--><!-- call(thisValue, arg1,arg2...): 1. 调用函数; (add.call();)2. 修改函数运行时的this指向; -->
</head><body><script>// [1.] 函数实例的call方法,可以指定函数内部this的指向,然后在所指定的作用域中,调用该函数。var obj1 = {};var fun = function () {return this;};console.log(fun() === window); //trueconsole.log(fun.call(obj1) === obj1); // true, call方法可以改变this的指向,指定this指向对象obj; // [2.] call方法的参数,应该是一个对象。如果参数为空、null和undefined,则默认传入全局对象(window)。var num = 123;var OBJ = {num: 456};function callback() {console.log(this);console.log(this.num);}callback.call();                // Window 123callback.call(null);            // Window 123callback.call(undefined);       // Window 123callback.call(window);          // Window 123callback.call(OBJ);             // OBJ 456// [3.] call的主要作用是实现继承function Father(uname, age, sex) {this.uname = uname;this.age = age;this.sex = sex;}function Son(uname, age, sex) {Father.call(this, uname, age, sex);}var son = new Son('刘德华', 18, '男');console.log(son);</script><!-- call方法的一个应用是调用对象的原生方法。(后话) --><script>var object = {};console.log(object.hasOwnProperty('toString')); //falseobject.hasOwnProperty = function () {return true;};console.log(object.hasOwnProperty('toString')); //true//使用call调用对象的原生方法console.log(Object.prototype.hasOwnProperty.call(object, 'toString')); //false//上面代码中,hasOwnProperty是obj对象继承的方法,如果这个方法一旦被覆盖,就不会得到正确结果。//call方法可以解决这个问题,它将hasOwnProperty方法的原始定义放到obj对象上执行,这样无论obj上有没有同名方法,都不会影响结果。</script>
</body></html>

(2)apply()方法

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><!-- apply方法的作用与call方法类似,也是改变this指向,然后再调用该函数。唯一的区别就是,它接收一个数组作为函数执行时的参数,使用格式如下。func.apply(thisValue, [arg1, arg2, ...])第二个参数则是一个数组,该数组的所有成员依次作为参数,传入原函数。原函数的参数,在call方法中必须一个个添加,但是在apply方法中,必须以数组形式添加。--><script>// (0) 初步使用function fun(num1, num2) {console.log(num1 + num2);}fun.call(null, 1, 3);fun.apply(null, [1, 4]);    //apply() 接受一个数组作为参数, 1、4依次作为fun()函数的参数  // (1) 找出数组最大元素// JavaScript 不提供找出数组最大元素的函数。结合使用apply方法和Math.max()方法,就可以返回数组的最大元素。// Math.max(value1, value2, ...) ; var arr = [10, 2, 3, 45, 1];console.log(Math.max.apply(null, arr));     // arr的所有成员依次作为参数,传入max函数, 相当于max(10, 2, 3, 45, 1)console.log(Math.max.apply(Math, arr));     // 这样写更为合适//(2) 将数组的空元素变为undefined (后话)//通过apply方法,利用Array构造函数将数组的空元素变成undefined。var array = ['a', , 'b'];Array.apply(null, array);console.log(array);         // ["a", empty, "b"]// 空元素与undefined的差别在于,数组的forEach方法会跳过空元素,但是不会跳过undefined。因此,遍历内部元素的时候,会得到不同的结果。var testArray = ['a', , 'b'];function print(value) {console.log(value);}testArray.forEach(print);                       // a b => 跳过了空元素Array.apply(null, testArray).forEach(print);    // a undefined b </script><script>//(3) 转换类似数组的对象 (后话)// 另外,利用数组对象的slice方法,可以将一个类似数组的对象(比如arguments对象)转为真正的数组。console.log(Array.prototype.slice.apply({0: 1,length: 1})); //[1]console.log(Array.prototype.slice.apply({0: 1})); //[]console.log(Array.prototype.slice.apply({0: 1,length: 2})); //[1,empty]console.log(Array.prototype.slice.apply({length: 1})); //[empty]// 上面代码的apply方法的参数都是对象,但是返回结果都是数组,这就起到了将对象转成数组的目的// 从上面代码可以看到,这个方法起作用的前提是,被处理的对象必须有length属性,以及相对应的数字键。var _A = new Array();console.log(_A);</script>
</body></html>

(3)bind方法1

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><!-- bind()方法用于改变函数体内this的指向, 然后返回一个新函数; bind()方法不会调用函数, 但是能改变函数内部的this指向; fun.bind(thisArg, arg1, arg2, ...); 返回值:返回由指定的this值和初始化参数改造的原函数拷贝; --><!-- 何时用?如果有的函数我们不需要立即调用, 但是又想改变这个函数内部的this指向, 此时用bind最合适了; -->
</head><body><button>点击</button><script>var object = {name: 'tom'}function fun(a, b) {console.log(this);      // this此时指向objectconsole.log(a + b);}var f = fun.bind(object, 1, 3);f();</script><script>// 我们有一个按钮, 当我们点击了之后, 就禁用这个按钮, 1秒后重新启用; // 法一:注意定时器中的this是window, 所以之前的做法是 var that = this, that.disabled = false;// 法二:bind(); var btn = document.querySelector('button');btn.onclick = function () { this.disabled = true;setTimeout(function() {this.disabled = false;}.bind(this), 1000);         // 此时定时器内部的this就是btn了 // 此处bind()函数中的参数可以是btn, 也可以是this, 都是代指btn; 但是this是最好的写法, 因为btn可能随时改变}</script>
</body></html>

(4)bind方法2

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><!-- bind()方法用于将函数体内的this绑定到某个对象, 然后返回一个新函数; bind()方法不会调用函数, 但是能改变函数内部的this指向; fun.bind(thisArg, arg1, arg2, ...); 返回值:返回由指定的this值和初始化参数改造的原函数拷贝; --><script>var d = new Date();console.log(d.getTime());var show = d.getTime;// show();         // Uncaught TypeError: this is not a Date object.// 上面代码中,我们将d.getTime方法赋给变量show,然后调用show就报错了。// 这是因为getTime方法内部的this,绑定Date对象的实例,赋给变量print以后,内部的this已经不指向Date对象的实例了。// bind方法可以解决这个问题:var print = d.getTime.bind(d);print();    //1613100200254</script><script>// bind方法的参数就是所要绑定this的对象var counter = {count: 0,inc: function() {this.count++;}};var func = counter.inc.bind(counter);   //意思是将counter对象的inc方方法绑定到counter对象上,然后赋值给funcfunc();console.log(counter.count); //1// 上面代码中,counter.inc方法被赋值给变量func。// 这时必须用bind方法将inc内部的this,绑定到counter,否则就会出错。</script><script>// bind还可以接受更多的参数,将这些参数绑定原函数的参数。var add = function(x,y) {return x * this.m + y*this.n;};var obj = {m: 2,n: 2};var newAdd = add.bind(obj,5);console.log(newAdd(5));     //20// 上面代码中,bind方法除了绑定this对象,还将add函数的第一个参数x绑定成5,// 然后返回一个新函数newAdd,这个函数只要再接受一个参数y就能运行了。// 如果bind方法的第一个参数是null或undefined,等于将this绑定到全局对象,函数运行时this指向顶层对象(浏览器为window)。function sum(x,y) {return x + y;}var plus = sum.bind(null,5);console.log(plus(6));   //11// 上面代码中,函数add内部并没有this,使用bind方法的主要目的是绑定参数x,// 以后每次运行新函数sum,就只需要提供另一个参数y就够了。console.log('----------');</script><script>// bind方法有一些使用注意点://(1) 每一次返回一个新函数;//(2)结合回调函数使用;// 回调函数是 JavaScript 最常用的模式之一,但是一个常见的错误是,将包含this的方法直接当作回调函数。// 解决方法就是使用bind方法var Counter = {count: 0,Inc: function() {'use strict';this.count++;}};function callIt(callback) {callback();}callIt(Counter.Inc.bind(Counter));console.log(Counter.count);     //1// 上面代码中,callIt方法会调用回调函数。// 这时如果直接把counter.inc传入,调用时counter.inc内部的this就会指向全局对象。// 使用bind方法将counter.inc绑定counter以后,就不会有这个问题,this总是指向counter。</script><script>var person = {age : 12,add: function() {this.age++;}};var Fun = person.add.bind(person);Fun();console.log(person.age);  //13</script>
</body>
</html>

(5)call-apply-bind区别

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><!-- 相同点:都可以改变函数内部的this指向; 不通点:1. call 和 apply 都会调用函数; 2. call 和 apply的区别在于call传递的是arg1, arg2...参数, 而apply传递的参数必须是数组形式; 3. bind 不会调用函数; 应用场景:1. call 经常做继承; 2. apply经常跟数组有关系; (比如借助数学对象实现数组最大值最小值) 3. bind 不调用函数, 还想改变this指向; (比如改变定时器内部的this指向) -->
</body>
</html>

2.8 函数的递归

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head><body><script>var num = 1;function fn() {if (num == 6) {return;} else {console.log('hello');}num++;fn();}fn();</script><script>//  求阶乘function fun(num) {if (num === 1) {return 1;}return num * fun(num - 1);}console.log(fun(3));</script><script>// 利用递归遍历数据: 输入id号, 返回对应的数据对象; // 存在重大bug( 后话 )var array = [{id: 1,name: '家电系列',goods: [{id: 11,gname: '冰箱系列',goods: [{id: 111,gname: '海尔冰箱'}, {id: 112,gname: '美的冰箱'}]}, {id: 12,gname: '洗衣机系列',goods: [{id: 121,gname: '1类洗衣机'}, {id: 122, gname: '2类洗衣机'}]}]}, {id: 2,name: '服饰系列'}];function getId(_array, id) {var obj = {}; _array.forEach(function(item) {if(item.id === id) {obj = item;} else if(item.goods && item.goods.length > 0) {obj = getId(item.goods, id); }})return obj;}console.log(getId(array, 1)); console.log(getId(array, 2)); console.log(getId(array, 11)); console.log(getId(array, 111)); console.log(getId(array, 112)); console.log(getId(array, 12)); console.log(getId(array, 121)); console.log(getId(array, 122)); </script> <script>function test() {return { name: 'XingWei', age: 23} ;}console.log(test());</script>
</body> </html>

2.9 闭包

(1)闭包1

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><!-- 1. 闭包: 指 有权访问另一个函数作用域中变量的 函数; 首先,闭包也是一个函数; 2. 闭包的作用:延伸了变量的作用范围;闭包的另一个用处,是封装对象的私有属性和私有方法; -->
</head><body><ul class="test"><li>hello</li><li>world</li><li>love</li><li>you</li></ul><script>// 1. fn就是一个闭包函数; function fn() {var num = 10;function fun() {console.log(num);}fun();}fn();// 2. 闭包的作用:延伸了变量的作用范围, 此时f()函数也可以使用num变量了! (num是函数中的局部变量, 默认不能在外面访问, 通过闭包延伸了变量的作用域范围)function Fun() {var num = 20;return function() {console.log(num);}}var f = Fun();f();</script>
</body></html>

(2)闭包2

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><script>// 由于在 JavaScript 语言中,只有函数内部的子函数才能读取内部变量,// 因此可以把闭包简单理解成“定义在一个函数内部的函数”。// 在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。// 闭包的最大用处有两个,一个是可以读取函数内部的变量,// 另一个就是让这些变量始终保持在内存中,即闭包可以使得它诞生环境一直存在。function createIncrementor(start) {return function () {return start++;}}var inc = createIncrementor(5);console.log(inc()); //5console.log(inc()); //6console.log(inc()); //7    //通过闭包,延长了内部变量start的生命周期// 上面代码中,start是函数createIncrementor的内部变量。// 通过闭包,start的状态被保留了,每一次调用都是在上一次调用的基础上进行计算。// 为什么会这样呢?原因就在于inc始终在内存中,而inc的存在依赖于createIncrementor,// 因此也始终在内存中,不会在调用结束后,被垃圾回收机制回收。</script><script>// 闭包的另一个用处,是封装对象的私有属性和私有方法。function Person(name) {var _age;function setAge(n) {_age = n;}function getAge() {return _age;}return {name: name,setAge: setAge,getAge: getAge,}}var p1 = Person('ZhangSan');p1.setAge(25);console.log(p1.getAge());// 上面代码中,函数Person的内部变量_age,通过闭包getAge和setAge,变成了返回对象p1的私有变量。// 注意,外层函数每次运行,都会生成一个新的闭包,而这个闭包又会保留外层函数的内部变量,// 所以内存消耗很大。因此不能滥用闭包,否则会造成网页的性能问题。</script>
</body></html>

(3)闭包案例

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><ul class="test"><li>hello</li><li>world</li><li>love</li><li>you</li></ul><script>// 1. 利用闭包的形式得到当前小li的索引号var lis = document.querySelector('.test').querySelectorAll('li');for (var i = 0; i < lis.length; i++) {// 创建4个立即执行函数(function (i) {lis[i].onclick = function () {console.log(i);}})(i);}// 2. 打车案例console.log('----------'); var car = (function () {        // 该函数就是闭包var start = 13; var total = 0; return {price: function (n) {if (n <= 3) {total = start;} else {total = start + (n - 3) * 5;}return total;},yongdu: function (flag) {return flag ? total + 10 : total;}}})();console.log(car.price(5));console.log(car.yongdu(false));console.log(car.yongdu(true));</script>
</body></html>

2.10 全局函数

(1)eval()

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><!-- 1. eval() 函数会将传入的字符串当做 JavaScript 代码进行执行; 2. eval()是一个全局的函数; 语法:eval(string); string: 一个表示JavaScript表达式、语句或一系列语句的字符串。表达式可以包含变量与已存在对象的属性; 返回值:返回字符串中代码的返回值。如果返回值为空,则返回 undefined; 3. 永远不要使用eval()!!! 它是一个危险的函数!!!-->
</head>
<body><script>/*1. 将字符串当做语句执行; eval('var a = 1;');console.log(a);             //上面的代码将字符串当做语句执行,生成了变量a*/eval('var a = 1;');console.log(a);         // 1/*2. eval没有自己的作用域,都在当前作用域内执行,因此可能会修改当前作用域的变量的值,造成安全问题; eval('a = 5');              // 此时,已经修改了外部变量a的值,由于这个原因,eval()有风险console.log(a);*/eval('a = 5');      console.log(a);    // 5/*3. 为了防止这种风险,JavaScript规定,如果使用严格模式,eval内部声明的变量,不会影响到外部作用域; (function(){'use strict';eval('var foo = 456;');// console.log(foo);   // error => foo is not defined})(); 上面代码中,函数f内部是严格模式,这时eval内部声明的foo变量,就不会影响到外部; 不过,即使在严格模式下,eval依然可以读写当前作用域的变量; (function() {'use strict';var foo = 1;eval('foo = 2; ');console.log(foo);   // 2})(); 上面代码中,严格模式下,eval内部还是改写了外部变量,可见安全风险依然存在; 此外,eval的命令字符串不会得到 JavaScript 引擎的优化,运行速度较慢。这也是一个不应该使用它的理由; */</script>
</body>
</html>

(2)isNan()

<!DOCTYPE html>
<html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title>
</head> <body><script>/*1. isNan(): 用来判断一个值是否为NaN(not a number); */console.log(isNaN(NaN));        // trueconsole.log(isNaN(123));        // falseconsole.log(isNaN({}));         // trueconsole.log(isNaN(['xyz']));    // trueconsole.log(isNaN([]));         // falseconsole.log(isNaN([123]));      // falseconsole.log(isNaN(['123']));    // false</script>
</body></html>

(3)parseInt()/Float()

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>/* 1. parseInt(string): 将字符串转为整数; 基本用法:1. 如果字符串头部有空格,空格会被自动去除; 2. 如果parseInt的参数不是字符串,则会先转为字符串再转换; 3. 字符串转为整数的时候,是一个个字符依次转换,如果遇到不能转为数字的字符, 就不再进行下去,返回已经转好的部分; 4. 如果字符串的第一个字符不能转化为数字(后面跟着数字的正负号除外),返回NaN; 5. 所以,parseInt的返回值只有两种可能,要么是一个十进制整数,要么是NaN; 6. 如果字符串以0x或0X开头,parseInt会将其按照十六进制数解析; 7. 如果字符串以0开头,将其按照10进制解析; 进制转换:1.parseInt方法还可以接受第二个参数(2到36之间),表示被解析的值的进制,返回该值对应的十进制数; 默认情况下,parseInt的第二个参数为10,即默认是十进制转十进制; */console.log(parseInt('1000', 10)); // 1000console.log(parseInt('1000', 2)); // 8console.log(parseInt('1000', 6)); // 216console.log(parseInt('1000', 8)); // 512/* 2. parseFloat(): 将一个字符串转为浮点数; 基本用法:1. 如果字符串符合科学计数法,则会进行相应的转换; 2. 如果字符串包含不能转为浮点数的字符,则不再进行往后转换,返回已经转好的部分; 3. parseFloat方法会自动过滤字符串前导的空格; 4. 如果参数不是字符串,或者字符串的第一个字符不能转化为浮点数,则返回NaN; 5. 尤其值得注意,parseFloat会将空字符串转为NaN; */</script>
</body>
</html>

3. 面向对象案例完善

https://gitee.com/xingweicoding/studys

JavaScript数组和函数相关推荐

  1. JavaScript 数组纯函数

    1. 常用的数组 API forEach 遍历所有元素,item 对应的是元素的值,index 对应的是元素的位置 let arr = [4, 6, 8]; arr.forEach(function( ...

  2. JavaScript数组,函数

    数组:多个元素的集合,数组是个有序列表 字面量创建数组: var arr1 = [ ] 数组内元素以逗号隔开,字符串加引号 数组长度 arr1.length 数组下标:从0开始 遍历数组:for(va ...

  3. Javascript数组函数库

    其实平时用的比较多的应该是push和pop,不过还是都记下来,以便后面使用. shift :删除原数组第一项,并返回删除元素的值:如果数组为空则返回undefined  var a = [1,2,3, ...

  4. Javascript - 1 引入方式,变量常量,数据类型,运算符,流程控制,数组,函数,对象,DOM

    Javascipt:是一门弱类型的脚本语言,需要在网页上执行. html负责框架结构,css负责样式修饰,js负责行为交互,动态效果. 前端三大件:html,css,js. javascript 和 ...

  5. JavaScript 数组 函数 对象

    数组 数组的概念 数组就是一组数据的集合,并且存储在单个变量名下 数组的创建方式 利用new创建数组 var 数组名 = new Array();var arr = new Array();//创建了 ...

  6. JS每日一题: JavaScript中的数组和函数在内存分别是如何存储的?

    要了解数组和函数在内存中如何存储的,首先的了解数组与函数属于什么数据类型 JavaScript数据类型 基本数据类型:Number.String.Boolean.Undefined.Null, 引用数 ...

  7. JavaScript二维数组与函数

    目录 一.二维数组 1.创建方式 2.访问二维数组元素 3.练习 (1)求3*4的二维数组的每行元素之和 (2)求3*4的二维数组的每列元素之和 (3)求3*3的二维数组的对角线元素之和 4.二维数组 ...

  8. [JavaScript] JavaScript数组挖掘,不只是讲数组哟(2)

    课程来源:后盾人 上一篇的内容:[JavaScript] JavaScript数组挖掘,不只是讲数组哟 数组引用类型分析,多维数组,用Array.of为数组创建细节,类型检测与转换,在一个数组后面加一 ...

  9. 浅析 JavaScript 中的 函数 uncurrying 反柯里化

    柯里化 柯里化又称部分求值,其含义是给函数分步传递参数,每次传递参数后部分应用参数,并返回一个更具体的函数接受剩下的参数,这中间可嵌套多层这样的接受部分参数函数,直至返回最后结果. 因此柯里化的过程是 ...

最新文章

  1. vue.js 源代码学习笔记 ----- 工具方法 lang
  2. java游戏移动_java - Java游戏 - 如何让敌人移动? - SO中文参考 - www.soinside.com
  3. HDU 1086 You can Solve a Geometry Problem too
  4. Mapreduce和Yarn概念,参数优化,作用,原理,MapReduce计数器 Counter,MapReduce 多job串联之ControlledJob(来自学习资料)
  5. Exchange 2013学习(六),脱机通讯簿
  6. keil中断函数的写法_在 KeilC里,中断子程序与函数有何不同?( )_学小易找答案
  7. gdb 调试_GDB调试指南-源码查看
  8. 计算机网络课设-小型校园网,计算机网络课设 小型校园网
  9. X-006 FriendlyARM tiny4412 u-boot移植之Debug串口用起来
  10. php mysql 双条件排序_php – 是否有通过匹配多个条件进行排序的SQL技术?
  11. php 什么是 cookie? 会话 cookie 与持久性 cookie 之间 有何区别?
  12. java编程求原码,补码_java语言基础(原码反码补码)
  13. 人工智能:一种现代方法 第四版 翻译序言
  14. PAT 乙级真题题解 java实现
  15. 自训练和半监督学习介绍
  16. 女生宿舍,男生请勿进
  17. python123第三单元测试卷_第三单元测试卷(带答案)
  18. 刷完这50个标准库模块:没人比我更懂Python了
  19. 数据结构算法常见的 100 道面试题全解析:2019 版
  20. 虚拟机安装Win10纯净版操作系统

热门文章

  1. TXT 小说 自动分章+排序工具
  2. 10G数据,1G内存,如何排序?
  3. ★【世龙最爱之作】☆【丑丫头变身美女校花,不恋情的人懊恼,可是有了爱情之后更烦恼】第七十九章★
  4. MYSQL-批量插入数据
  5. ListBox选中项数量显示于TextBox文本框中
  6. java计算机毕业设计医院住院部信息管理系统源码+数据库+系统+lw文档+mybatis+运行部署
  7. java反射机制 知乎_你能说说Java中的反射机制吗?
  8. R700指令集架构参考手册
  9. oracle tpch建表语句,Linux/Mac下tpch工具生成数据集
  10. 关于 JS 的脚本执行及 SetTimeOut延迟时间为0的详解