JavaScript笔记-4
2019-03-26 本文已影响0人
蚂蚁踩死我
作用域
- 作用域决定了变量、常量和参数被定义的时间和位置
- 形参只有在函数被调用的时候才变成实参,函数返回后参数就失去作用域
- 变量和常量只有在创建后才存在,使用let、const声明前,他们是没有作用域的
- var
作用域和存在
-
作用域
- 当前可见并且可被正在执行的代码块访问的标识符
存在
- 保存了已经分配过内存的数据的标识符
静态作用域与动态作用域
JavaScript中,作用域是静态的
- 静态作用域
- 在某个作用域内定义函数,该作用域包含的所有变量也在该函数的作用域内。
- 静态作用域适用于全局作用域、块作用域、函数作用域。
全局作用域
全局作用域中声明的一切在所有作用域中都可用,所以要谨慎使用全局变量
块作用域
Let 和 const 声明的变量名处在块作用域中
变量屏蔽
独立外部块的同名变量,屏蔽了外部块定义的变量
const obj = {
color: 'red'
},
objCopy = obj,
number = 100;
function fun() {
const number = '一百';
console.log(number);
objCopy.color = '红色';
}
fun(); //一百
console.log(number); //100
console.log(obj); //{color: "红色"}
console.log(objCopy); //{color: "红色"}
函数、闭包和静态作用域
-
闭包
故意将函数定义咋一个指定的作用域中,并明确地指出它对该作用域具备访问权限
let fun ; { fun = function(){ console.log(color) ; } ; const color = 'red' ; } fun() ;
闭包内定义的函数还允许访问一些正常情况下无法访问到的信息。
let fun; { const list = {}; fun = function (name) { return list; }; } const newList = fun(); newList.color = 'pink' ; console.log(newList) ;//{color: "pink"} console.log(fun()) ;//{color: "pink"} console.log(list) ;//list is not defined
即时调用函数表达式
(function(){
//代码
}) () ;
好处是,任何内部信息都有自己的作用域,并且因为它本身就是函数,它可以向作用域外传递信息。
-
即时调用函数作用域内,变量是安全的,外部不能访问它。
-
可以从即时调用函数返回任何想要的结果,笔记常见返回数组、对象、函数。
-
可以打印出自己被调用的次数,而且不会被篡改
const message = (function () { let sum = 0; const str = '又大又宽又圆'; return function () { console.log(`信息的长度是${str.length}, \n` + `你是第${++sum}获得提示的人。`); } ; })(); message() ;//信息的长度是6, //你是第1获得提示的人。 message() ;//信息的长度是6, //你是第2获得提示的人。 message() ;//信息的长度是6, //你是第3获得提示的人。
函数作用域和提升
var 声明的变量,可在当前作用域的任意地方可用,甚至可以在声明前使用。
任何使用var声明的变量都会被提升到作用域顶部,提升不是赋值。
/*
*JavaScript解释下面代码的方式:
*
* var a ;
* var y ;
* console.log('第一次打印a :'+a) ;
* if(a !== 0){
* console.log('第一次打印b :'+b) ;
*
* b = 1 ;
*
* if(b){ a = 0 ;}
*
* console.log('第二次打印b :'+b) ;
* }
*
* if(a === 0) console.log('第三次打印b :'+b) ;
*/
console.log('第一次打印a :'+a) ;
if(a !== 0){
console.log('第一次打印b :'+b) ;
var b = 1 ;
if(b){ var a = 0 ;}
console.log('第二次打印b :'+b) ;
}
if(a === 0) console.log('第三次打印b :'+b) ;
同一函数或全局作用域内,var不能用来创建新的变量,变量屏蔽现象也不会出现
//使用var后,变量屏蔽现象不会出现
var number = 1000 ;
if(number === 1000){
var number = 999 ;
console.log(number) ;//999
}
console.log(number) ;//999
//使用let
let number = 1000 ;
if(number === 1000){
let number = 999 ;
console.log(number) ;//999
}
console.log(number) ;//1000
函数提升
函数声明也会被提升至他们作用域的顶部
临时死区
在ES6中没有必要使用typeof来检查变量是否被定义
严格模式
代码第一行插入字符串"use strict"
- 不建议在全局作用域使用严格模式,它会应用于所有代码,多人协作合并代码容易出错
- 建议在单独函数中开启严格模式,或者将所有代码封装在一个立即执行的函数中。
数组
操作数组
-
会修改原数组*
方法 描述 .push()
数组最后添加元素,return新数组长度 .pop()
数组最后删除元素,return被删除的元素 .shift()
删除数组第一个元素,return被删除的元素 .unshift()
添加数组第一个元素,return返回新数组长度 .reverse()
颠倒当前数组得顺序 .sort()
对当前数组进行排序,接受一排序函数作为参数 ES6新方法 描述 .copyWithin
将数组中一段元素复制到数组得另一个位置,
并覆盖此位置的原来元素,
第一个参数 复制到哪
第二个参数 从哪里开始复制
(可选)第三个参数 复制多少个参数.fill()
将一个固定值赋值给数组中任意位置元素 const arr = [1, 2, 3, 4]; console.log(arr) ;//[1, 2, 3, 4] arr.copyWithin(2, 1, 3) ; console.log(arr) ;//[1, 2, 2, 3] arr.fill('a', -2, -1) ; console.log(arr) ;//[1, 2, "a", 3]
-
不会修改原数组,返回新数组
方法 描述 .concat()
给数组添加多个元素,return新数组 .slice()
获取数组得子数组,return子数组 .filter()
比较麻烦,执行百度 -
不会修改原数组,返回其他
方法 - .indexOf()
返回和查找的内容完全相同的第一个元素下标,没找到返回-1,第二参数接受起始下标 .lastIndexOf()
返回和查找的内容完全相同的倒数第一个元素下标,没找到返回-1,第二参数接受起始下标 .findIndex()
接受一个匹配函数作为参数,返回查找到的元素下标,否则返回-1 .findLastIndex()
接受一个匹配函数作为参数,返回查找到的元素下标,否则返回-1 .find()
返回查找到的第一个元素本身 .reduce()
自行百度 //reduce用法 const arr = [1, 2, 3, 4] ; //(a, el)回调函数参数,a为累加起始值(此处为100),el数组元素 const b = arr.reduce((a, el) => a+el , 100) ; console.log(b) ;//110 //reduce 进阶用法 const arr = [ 'Bosd', 'Go98', 'Ixj', 'Eoo', 'Ajv', 'Clsq', 'Avi', 'Fk.x', 'Cro2v', 'D0we', 'Ezxp', 'G3io', 'I-l' ] ; const newArr = arr.reduce((a, el) => { if(!a[ el[0] ]) a[ el[0] ] = [] ; a[el[0]].push(el) ; return a ; }, {}) ; console.log(newArr) ; /* { A: ["Ajv", "Avi"] B: ["Bosd"] C: ["Clsq", "Cro2v"] D: ["D0we"] E: ["Eoo", "Ezxp"] F: ["Fk.x"] G: ["Go98", "G3io"] I: ["Ixj", "I-l"] } */
const arr = [
1,
'a',
true,
{name: 'Tom'},
null,
23,
'b',
{color: 'red'},
false
] ;
const a = arr.find(
(el, i) => i > 2 && typeof el === 'object'
) ;
console.log(arr) ;//[1, "a", true, {…}, null, 23, "b", {…}, false]
console.log(a) ;//{name: "Tom"}
-
即修改原数组,也返回新数组
方法 描述 .splice()
第一个参数修改元素位置
第二个参数删除元素个数
其他参数是添加到数组得元素
return被删除的元素
数组方法,已删除或者未定义的数组
当数组中的元素未被赋值或已被删除,map,filter,reduce就不会调用所传入的函数。
一般情况不会对数组使用delete,会造成数组缺口
字符串连接
Array.prototype.join()方法接受一个分隔符作为参数,返回一个连接了所有元素的字符串
const arr = [1, 'a', true, undefined, null, NaN, {}, '', [] ] ;
const a = arr.join('?') ;
console.log(a) ;//1?a?true???NaN?[object Object]??