此篇文章完全按照我个人理解去写。
1. 何为 JS
先说说 js 干啥的。不负责点说,js 就是操作浏览器的。
有人可能说 nodeJS,nodeJS 严格意义上只能说是用的 ES, 因为他没有 dom,也没有 bom。
简单点说,js = EcmaScript + dom + bom
那么就引申到 EcmaScript,dom,bom;
EcmaScript 简称 es,是一种脚本语言,也就是 javaScript 语法的依据,或者说标准。jS 是在 es 的基础上做了一些扩展。
而 常说的 es6 就是 第六版 EcmaScript,正式发行与 2015 年,所以 es6 往往也称为 es2015。
dom 一般就是节点,而 bom 就是浏览器对象。
节点很好理解,就是 div 之流,而 浏览器对象也很好理解,就是 url 什么的。
然后说说 js 单线程的事情,线程和进程这个大家自行查询,网上有很简洁清晰的一些描述,我高考语文不及格,不如别人说的清楚。只说单线程的运行模式。
2. 单线程
单线程 是从上至下运行的。目前我所知的唯一能摆脱这个顺序的就是异步。
3. 异步
异步的原因如果不专业点说,就是因为浏览器只是 js 的宿主,它并不是单线程的。
我曾经傻乎乎地想利用异步来实现多线程的效果,果不其然呀,我想太多了。
因为同一时间,js 只能处理一个异步,这又牵扯到单线程问题了。
异步相当于只是浏览器借了块地儿给 js,最后运行还得跑到 js 里面来。
说说我当时跑的多异步代码呀。
let i = 0;
for(let n = 0; n < 10; n ++) {setTimeout(function(){while(i < 10000) {console.log('this is' + n +'async');
i ++;
}})
}
然后控制台默默打印了 10000 个 this is 0 async
目前前端,异步主要为 前后端交互 以及 定时器,仅仅说前端,如果说 nodeJS 的话,还有文件读取等其他的方面会异步。
回调函数
回调函数就是写在异步方法里面的 function,其原理是利用了 js 的单线程,异步完成 -》异步处理 -》处理回调函数,所以一般回调函数都是写在异步的最后。
比如封装一个 $.ajax
function requestApi(url, method, data, cb) {
$.ajax({
url: url,
type: method,
data: data,
success: function(res) {if(res.code === 1) {cb(res.data);
}
}
})
}
然后就可以很潇洒地写一个,request('apiUrl', 'get', {}, function(data){console.log(data)});
ajax 看着嫌麻烦的话,看定时器版本的
function callback(data){console.log(data)};
setTimeout(function(){var i = 3; callback(i)}, 1000);
扯一句:nodeJS 的高并发就是用异步来实现的。
然后说一下 JS 的基本用法。
JS 的分基本数据类型 Number,String,Boolean,Undefined,Null,Symbol 和 复杂数据类型 Object
所以不要再说 JS 中万物皆对象了,那个就是欺骗新手的。
有人可能要说 a = ‘123’;a.length = 3; a 明明也是一个对象,因为有 length 这个属性。
两年前我也是这么认为的,实则不然。
a 就是一个 字符串 ‘123’,之所以可以写 a.length 是因为弱类型语言对玩家们要求比较宽松,当你写 a.length 的时候,会立刻给 a 包装一个临时对象 new String(a),然后去调用这个临时对象的 length, 然后调用完成再抛掉。
Number 不用讲了,就是数字,幼儿园就开始学的。
String 也不用讲了,就是字符,幼儿园估计也开始学了。
Boolean 是布尔值,除了 true 就是 false,可以看做开关。
Undefined 是一个特殊的类型,表示没有被赋值。这个要区别于 not defined,undefined 表示,可以有,没赋值,not defined,表示 没有被定义,简称未定义。
Null 表示空对象,是一个比较牛逼的对象。
symbol 通俗点讲吧。就是 …symbol(1) 不等于 symbol(1), 这话意思就是,每一个 symbol 都是唯一的,即便里面传值一样。
Object 对象,或称引用类型,区别于基础对象的是在于内存方面,找个时间写 js 非基础语言分析的时候,再详细说,如果需要了解,请自行查询,这个涉及到一些指针,内存方面的问题,虽然本人理解得很到位,但是高考语文不及格,解释起来比较费劲,一般情况下我都去画画解释。
常用的对象方法(String 对象,Array 对象,还有字典);
String 对象 区别于 string,string 是字符串,string 对象是 Object,具体解释可以看上面的
这里假设 a = '123456', b = '1|2|3|4'
charAt: 用法 a.charAt(1) // 2 相当于 a[1]
split : 用法 b.split('') //[1,2,3,4] 表示拆分,split 的括号里面写拆分依据
replace: 用法 b.replace(/\|/g, '')// 1234 表示替换,一般情况下两个参数,前面的是一个正则,表示需要筛选的内容,后面的是替换内容或者处理方法,这个方法是 string 对象里面最牛逼的方法,牛逼到正则玩得溜就可以批处理很多东西,正则的话,我有写过一个简版教程,勉强能看一下。indexOf: 用法 a.indexOf(3)// 2 寻找满足条件的第一个字符串的位置
lastIndexOf: 用法 和 a.lastIndexOf(3)//2 意思和 indexOf 相反,是最后一个的位置
注意:string 所有的方法均不会改变原 string 对象,也就是说,所有的提取,都需要一个新的变量去接受,比如 xx = a.chartAt(1);
Array 对象 简称数组 实质是也是一个对象,索引为 0 ~ n
开发中用的最多的对象,常用方法
假设 arr = [0]; arrs = [1,2,3,4,5]// 语法糖,空数组
push:用法 arr.push(1)// 往尾部新增数据,arr 会变成[0, 1] 并且返回 1,返回 1 的意思就是,加入 c = arr.push(1)。c 的值为 1
pop: 用法 arr.pop()// 从尾部提取数据,arr 会重新变成[0], 并且返回 1
unshifit: 用法 arr.unshift(1)// 往头部新增数据,arr 变成[1, 0], 并返回 1
shift:用法 arr.shift(1)// 从头部提取数据,arr 变成 [0], 并返回 1
join:用法 arrs.join('|')// 拆分并以 | 区别,返回 1|2|3|4|5
concat: 用法 arr.concat(arrs)// 合并,合并内容可以是各种类型数据,这里返回 [0,1,2,3,4,5]
find: 用法 arrs.find(data => data > 3) // 返回 4 表示第一个满足条件的
fingIndex: 用法 arr.findIndex(data => data > 3) 返回 3 表示第一个满足条件的数字的索引
Index 和 lastIndex 和 string 用法相同
some: 用法 arrs.some(data => data > 3) // 返回 true 或者 false,表示有没有满足条件的,如果有的话,返回 true,这个 some 和 find 操作方面比较骚气,一般配合其他操作,之所以说操作,是因为他一旦判断到有,就会立即停止后面的遍历,如果这里写
arrs.some(data => {console.log(data);return data > 3}; //1 2 3 4 不会去打印 5, 可以用于 break 操作
forEach: 用法 arrs.forEach(data => console.log(data));//1 2 3 4 5 类似于批处理, 好像不能 break,无返回值
map: 用法和 forEach 一样,但是会有返回值,把批处理的方法每一次结果封装成数组返回,如果处理中不写 return , 则返回一堆[undefined, undefined]
reduce: 这个方法比较复杂,一共两个参数,前面是方法,后面是初始值(可以不写),前面的方法需要俩个参数。简单点说呀,就是从默认值或者从数组第一个值(取决于有没有默认值)每次处理两个值,这两个值呢,第一个是上一次处理完成返回的值,第二个是新值。arrs.reduce(function(a, b) {console.log(a, b);return a + b}, 10);
打印就是 // 10 1 , 11 2 , 13 3, 16 4 ,20 5 最后返回一个 25
arr 的 pop ,shift,push ,unshift 方法会改变原数组,其他不改变原来数组的方法一般还有第三个参数,相当于 bind,用来改变 this 指向
Object,或者说 JSON,或者说字典
我实在是编不下去了,
形式就是 key: value 的格式
主要用于完成数据结构与算法。
假设 obj = {age: 3};
常用方法一般都比较牛逼,这里只要会 obj.sex = 0;
obj[‘age’] //3
Object.keys(obj) // age, sex
Object.values(obj) // 3, 0
其他的方法等我哪天心血来潮写非基础知识点的时候再写吧