基础语法
注释
- //
- /* ... */
数据类型
- Number
- 字符串
- 布尔值
- 与运算:&&
- 或运算:||
- 非运算:!
- 比较运算符
- ==比较,它会自动转换数据类型再比较
- ===比较,它不会自动转换数据类型,如果数据类型不一致,返回false,如果一致,再比较。
- NaN这个特殊的Number与所有其他值都不相等,包括它自己(可以使用isNaN()函数进行判断)
- null and undefine
- 数组
- [element_a,element_b,element_c]
- New Array(element_a,element_b,element_c) //创建数组同a
- 对象
var person = {
name: 'Bob',
age: 20,
tags: ['js', 'web', 'mobile'],
city: 'Beijing',
hasCar: true,
zipcode: null
};
获取一个对象的属性,我们用对象变量.属性名的方法
变量
- var
- strict模式(强制通过var申请变量,未使用则报错)
字符串
- 使用 \ 进行转义
- \x## 使用十六进制asciii
- \u#### 使用unicode
- 多行字符串
`这是一个
多行
字符串`;
- 模版字符串
- 使用 + 进行连接
- 使用$引用变量(需要使用反引号进行引用)
- 字符串的常用操作
- str.length ->获取长度
- str[number]->进行取出
- str.toUpperCase()->全部转成大写字符串
- str.toLowerCase()->全部转成小写字符串
- str.indexOf('word')->搜索指定字符串出现的位置,没找到则返回-1
- str.substring(0,5)->返回索引区间在[0,5)的字符串,str.substring(7)->索引7开始到结束
数组
- array.length->获取长度(可以对其赋值而改变长度,未定义则)
- array.indexOf()->搜索指定元素的位置,没有则返回-1
- slice()->同substring同样的用法(若不指定参数,则从头到尾截断,利用这一个特点可以深拷贝一个新的数组
- push()、pop()->从尾部添加、返回删除元素(空组继续pop返回undefined)
- unshift()、shift()->从首部添加、返回删除的元素(空组返回undefined)
- sort()->排序
- reverse()->反转数组
- splice(start_index,number,add_element1,add_element2)->返回删除的元素并添加新元素
splice(start_index,number)->只返回删除的元素
splice(start_index,0,add_emelemt1,add_element2)->只添加元素,返回[]
- array_1.concat(array_2)->合并两个数组
- array.join('str')->在每两个元素之间添加str
对象
var object = {
name: '小明',
birth: 1990,
school: 'No.1 Middle School',
height: 1.70,
weight: 65,
score: null
};
- 使用object.key->得到value
- 使用object[key]取出值
- 访问属性是通过.操作符完成的,但这要求属性名必须是一个有效的变量名。如果属性名包含特殊字符,就必须用''括起来
var object = {
name: '小红',
'middle-school': 'No.1 Middle School'
};
如上,取出middle-school的时候需要使用object['middle-school']
- 访问不存在的key时,返回undefined
- 直接使用object.key=value / object[key] = value 进行添加,同时可以使用delete进行删除
- 'key' in object 可以判断是否存在对应的key
- 要判断一个属性是否是 object 自身拥有的,而不是继承得到的,可以用hasOwnProperty('key')方法
条件判断
if else if else{};
循环
- for( A; B; C)
- for(... in ...) -> 对于array类型的可以看作key为索引
- for(... of ...)
- while
- do while
Map & Set(ES6)
- 使用 new Map() / new Set()进行创建
- Map: set(key,value)、has(key)、get(key)、delete(key)
- Set: 不重复的集合add(key)、 delete(key)
iterable
使用 for ... of ...进行可迭代对象遍历。
forEach方法,接收一个函数,每次迭代就自动回调该函数
函数
- 定义函数与调用
- function xxx(x,y,z)
- var func_name = function (x);
- arguments->获取目前函数传入的所有
- 变量提升,js会提升声明,但不会提升赋值。
- 全局作用域:绑定到window的一个属性上
- 名字空间
- 局部作用域
- let替代var可以申请一个块级作用域
- 常量:const
- 解构赋值: var [x,y,z] = [a,b,c],
在对象中,如果要使用的变量名和属性名不一致可以使用old_key:new_key进行表达
- 解构时可以设置默认值,也可以跳过
方法
- 可以为对象的绑定一个函数(绑定到对象的函数称之为方法)
- this函数总是指向当前对象
- 特殊用法
- apply ->控制this的指向
func.apply(需要绑定this的变量,array表示函数本身需要传入的参数)
function getAge() {
var y = new Date().getFullYear();
return y - this.birth;
}
var xiaoming = {
name: '小明',
birth: 1990,
age: getAge
};
xiaoming.age(); // 25
getAge.apply(xiaoming, []); // 25, this指向xiaoming, 参数为空
- apply 和 call 区别:apply是将参数打包array传入,call把参数按照顺序传入。
- 装饰器:
- 封存原函数
- 使用window修改现函数,添加计数函数
- 返回 利用apply实现原函数的调用
高阶函数
高阶函数实际上就是接收另一个函数作为参数的函数。
- map:接收一个函数,将该函数逐个作用到可迭代对象上 iterable.map(function)
- reduce:接受一个函数,且该函数必须接收两个参数。将结果继续和序列的下一个元素进行计算。
attention:
map方法的函数只要一个参数,但是map传递的参数有三个,分别是:数组元素、元素索引,数组本身,而paresInt是可以接受两个参数的,第一个是字符,第二个是进制。
['1', '2', '3'].map(paresInt)
相当于
['1', '2', '3'].map(paresInt(value, index))
执行的内在逻辑就是:
第一个元素就是:paresInt('1', 0) > 1
第二个元素就是:paresInt('2', 1) > NaN
第三个元素就是:paresInt('3', 2) > NaN
- filter:类似map的使用,将函数作用到可迭代对象中,返回函数判断为真的元素
回调函数:filter(function(element,index,self)) 通常我们仅使用第一个参数,表示Array的某个元素。回调函数还可以接收另外两个参数,表示元素的位置和数组本身。
- sort:在JS中是将元素转换成string后进行排序(大坑),不过sort可以接收一个函数进行排序
- Array:
- every():判断数组元素是不是都满足测试条件
- find():查找符合条件的第一个元素
- findIndex():返回符合条件的第一个元素的索引值
- forEach():用于遍历可迭代对象
闭包
把函数作为一个返回值称之为闭包,其内部局部变量还引用外部变量(重点)
tips:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
匿名函数
例子1:(function(x){ return x*x; })(3);
例子2:
(function(x){
return x*x;
})(3);
箭头函数
Arrow function: 类似于匿名函数
x =>x*x
相当于
function(x){
return x*x;
}
对于多条语句的箭头函数,使用以下形式
x => {
... 且必须包含return语句...
}
两个参数则需要使用括号包含
(x,y) => x+y;
生成器
function* (x,y,z){
yield x;
yield y;
return z;}
可以使用next()或者for ... of ... 进行循环迭代
标准对象
- 在JS中所有都是对象,使用typeof得到个对象的类型返回的字符串如下
- 包装对象
number、boolean、string都有包装对象,可以用new进行创建。并且创建出来的值虽然一模一样但是类型却变成了object,所有用===进行判断是会返回false
- 总结:
- 不要使用new Number()、new Boolean()、new String()创建包装对象;
- 用parseInt()或parseFloat()来转换任意类型到number;
- 用String()来转换任意类型到string,或者直接调用某个对象的toString()方法;
- 通常不必把任意类型转换为boolean再判断,因为可以直接写if (myVar) ;
- typeof操作符可以判断出number、boolean、string、function和undefined;
- 判断Array要使用Array.isArray(arr);
- 判断null请使用myVar === null;
- 判断某个全局变量是否存在用typeof window.myVar === 'undefined';
- 函数内部判断某个变量是否存在用typeof myVar === 'undefined'
tips:整形使用toString()方法时,需要按照如下使用:
123..toString() 或者 (123).toString()
Date
- 创建一个指定日期:new Date(2020,11,25,12,0,0,0); JavaScript的月份范围用整数表示是0~11
- Date.parse('2020-05-15T19:01:05.123+08:00');转换成时间戳格式
RegExp
- 正则表达式:
\d:匹配一个数字 | \w:匹配一个字母或数字 | . :匹配任意一个字符 |
---|---|---|
*:匹配0个或者多个 | +:匹配至少1个 | ?:匹配0个或者1个 |
\s:匹配一个空白符 | {m,n}:表示匹配m-n个 | 特殊字符:使用 \ 转义 |
[0-9a-zA-Z]:进行匹配 | ^:表示开头 | $:表示结尾 |
- JS中两种正则的写法
- 使用两个斜杠包裹住 re1 = / string /
- re2 = new Reg(' string ')
使用方法是 RegExp对象.test(待匹配字符串)
- 切分字符串:split(正则)
- 分组:将正则的规则使用括号分组,进行匹配时会将匹配到的分组进行提取。如果正则表达式中定义了组,就可以在RegExp对象上用exec()方法提取出子串来。
- 贪婪匹配:就是会优先匹配尽可能多的子序列,使用 +?组合进行非贪婪匹配。
- 全局搜索:
JavaScript的正则表达式还有几个特殊的标志,最常用的是g,表示全局匹配:
var r1 = /test/g;
// 等价于:
var r2 = new RegExp('test', 'g');
当我们指定g标志后,每次运行exec(),正则表达式本身会更新lastIndex属性,表示上次匹配到的最后索引:
JSON
JSON的字符串规定必须用双引号"",Object的键也必须用双引号""
- 序列化:将对象转换成json:JSON.stringify(object_name[,function,'格式'])
- 反序列化:将json转换成对象:JSON.parse(json,[function])
面向对象编程
JS不通过类和实例的概念,而通过原型来实现面向对象编程。
JS中所有对象都是一个实例,所谓的继承关系不过是从一个对象指向另一个对象。
- obj.proto = other_obj;(不要直接用)
- var new_obj = Object.create(old_obj);
- var new_obj = new Object(old_obj);
创建对象
使用new进行创建新对象。如果不写new就是一个普通的函数。
function obj_student(name){
this.name = name;
this.hello = function(){
alert('hello ' + this.name);
};
}
var new_stu = new obj_student('hcy');
原型链:new_stu-->obj_student.prototype-->Object.prototype-->null
要让创建的对象共享一个函数,可以通过将函数移动到新对象共同的原型上(obj_student.prototype上即可)
obj_student.prototype.hello = function(){...};
原型继承
- 定义新的构造函数,并在内部用call()调用希望“继承”的构造函数,并绑定this;
- 借助中间函数F实现原型链继承,最好通过封装的inherits函数完成;
- 继续在新的构造函数的原型上定义新方法。
class继承
- class
回顾用函数实现Student的方法:
function Student(name) {
this.name = name;
}
Student.prototype.hello = function () {
alert('Hello, ' + this.name + '!');
}
用新的class关键字实现如下:
class Student{
constructor(name){
this.name = name;
}
hello(){
alert('hello,' + this.name +'!');
}
}
class定义包含了构造函数constructor和定义在原型对象上的函数(不需要function),最后创建一个student对象代码和前面一样。
var new_obj = new Student('robot');
new_obj.hello();
- class继承
class primaryStudent extends Student{
constructor(name,grade){
super(name);//用super调用父类构造方法
this.grade = grade;
}
myGrade(){
console.log(this.grade);
}
}
Extends 则表示原型链对象来自Student。 子类的构造函数可能不一样。例如primaryStudent需要name和grade,并且需要super(name)来调用父类的构造函数,否则父类name属性无法正常初始化。
Window
window对象不仅充当全局作用域,而且表示浏览器窗口。可以使用innerWidth 和innerHeight两个属性来获取页面的净宽高。使用outerWidth和outerHeight来获取整个浏览器窗口的宽高。
Navigator
表示浏览器的信息,属性包括:
- navigator.appName:浏览器名称;
- navigator.appVersion:浏览器版本;
- navigator.language:浏览器设置的语言;
- navigator.platform:操作系统类型;
- navigator.userAgent:浏览器设定的User-Agent字符串。
Screen
表示屏幕的信息,属性包括:
- screen.width:屏幕宽度,以像素为单位;
- screen.height:屏幕高度,以像素为单位;
- screen.colorDepth:返回颜色位数,如8、16、24。
Location
表示当前页面的URL信息。
location.href; //http://www.example.com:8080/path/index.html?a=1&b=2#TOP
location.protocol; // 'http'
location.host; // 'www.example.com'
location.port; // '8080'
location.pathname; // '/path/index.html'
location.search; // '?a=1&b=2'
location.hash; // 'TOP'
可以使用location.assign()加载一个新的页面,location.reload()重新加载当前页面。
Document
表示当前页面,HTML在浏览器以DOM表示为树形结构,document相当于DOM树的根节点。
可使用getElementById() / getElementByTagName()按照ID/Tag Name获取一组节点。
使用document.cookie;可以获取当前的页面的cookie,服务器在设置Cookie时可以使用httpOnly,设定了httpOnly的Cookie将不能被JavaScript读取。这个行为由浏览器实现,主流浏览器均支持httpOnly选项。
history
保存浏览器的历史记录,可以调用back() / forward()相当于后退和前进。(不适用)
操作DOM
- 由于ID在HTML文档中是唯一的,所以document.getElementById()可以直接定位唯一的一个DOM节点。document.getElementsByTagName()和document.getElementsByClassName()总是返回一组DOM节点。要精确地选择DOM,可以先定位父节点,再从父节点开始选择,以缩小范围。
- 使用querySelector()和querySelectorAll(),需要了解selector语法,然后使用条件来获取节点
更新DOM
- 修改innerHTML
- 修改innerText或者textContent (innerText不返回隐藏元素的文本,而textContent返回所有文本。另外注意IE<9不支持textContent)
插入DOM
- parent_Element.appendChild()
- parent_Element.insertBefore(new_Element,referenceElement),子节点会插入到referenceElement之前
删除DOM
- parten.removeChild(children)
操作表单
< input type= "xxx">其中xxx分为text/password/radio/checkbox/hidden代表文本/口令/单选/多选/隐藏文本。< select>下拉框。
获取值/设置值:可以直接调用value获取对应的用户输入值。但是对于单选/复选返回的属性永远是HTML的预设值,要获取实际的用户选项需要使用checked判断。
控件
HTML5新增了大量标准控件,常用的包括date、datetime、datetime-local、color等,它们都使用< input>标签
提交表单
- 通过
- 响应
<!-- HTML -->
<form id="test-form" onsubmit="return checkForm()">
<input type="text" name="test">
<button type="submit">Submit</button>
</form>
<script>
function checkForm() {
var form = document.getElementById('test-form');
// 可以在此修改form的input...
// 继续下一步:
return true;
}
</script>
- 没有name属性的< input>的数据不会被提交
操作文件
HTML中唯一可以上传的控件是< input type = "file">,在包含上传控件时表单enctype必须指定为multipart/form-data,method必须指定为post,浏览器才能正常编码。
tips:JS无法修改type="file"的value赋值。
File API
File和FileReader两个对象,可以获取文件信息并且读取文件
回调
JS中执行代码总是以单线程模式执行的,处理多任务时是以异步调用的形式执行的。
比如上面的代码:
reader.readAsDataURL(file);
就会发起一个异步操作来读取文件内容。因为是异步操作,所以我们在JavaScript代码中就不知道什么时候操作结束,因此需要先设置一个回调函数:
reader.onload = function(e) {
// 当文件读取完成后,自动调用此函数:
};
当文件读取完成后,JavaScript引擎将自动调用我们设置的回调函数。执行回调函数时,文件已经读取完毕,所以我们可以在回调函数内部安全地获得文件内容。
AJAX
- 依赖XMLHttpRequest对象进行写AJAX。
- 安全限制:URL使用相对路径,因为AJAX请求时,必须和当前页面完全一致(域名相同、端口相同、协议相同)
- CORS:跨域资源策略。假设本域是 my.com,外域是 sina.com,只要响应头Access-Control-Allow-Origin为http://my.com,或者是*,本次请求就可以成功。
Promise
Promise().then().then....catch() 多任务串行执行.
情景化记忆:在一个任务链中,比如我要向上级部门一层层的往上提交申请,if(某种条件)承诺帮你resolve解决问题,else承诺reject你的请求. 他给出的resolve问题的办法只是个空头Promise,then到总经理那实现具体承诺,如果总经理还是给一个空头承诺(返回Promise实例),还得then到董事长那里.... 任一一步做出的是reject的承诺,还有什么好说的,被拒绝了,后面的就不会再往上走了呀. 准备catch 拒绝通知吧blablabla
Promise.all([p1,p2,...]) 多任务并行执行
都要成功才进入then,返回结果数组.
Promise.race([p1,p2,...]) 多任务赛跑.
then()和catch(),谁先调用算谁的,其它任务中断.
Canvas
...
jQuery
- 消除浏览器差异
- 简洁操作DOM
- 轻松实现动画以及修改CSS等操作
$:变量JQuery的别名,本质上就是一个函数,但函数也是对象,于是$除了可以直接调用以外还能有其他很多属性。
选择器
- 按ID查找:
// <div id = "abc">
var id_ = $('#abc');
需要以#开头,返回的是一个jQuery对象。不存在则返回 [ ]
- 按tag查找:
只需要写上tag名称就可以了。
var ps = $('p'); //返回所有<p>节点
ps.length; //返回<p>节点数
- 按class查找:
需要在class名称之前加一个**.**
var a = $('.red'); //所有节点包含class="red"都将被返回
// 例如:
// <div class="red">...</div>
// <p class="green red">...</p>
- 按属性查找
一个DOM有许多属性可以查找,如:
var email = $('[name=email]'); //找出 <??? name="email">
var pwd = $('[type=password]'); //找出<??? type="password>
var a = $('[item="A B"]'); //找出<??? items="A B">
当属性的值包含空格等特殊字符时,需要用双引号括起来
还可以使用前后缀查找:
var icons = $('[name^=icon]'); //找出所有name属性值以icon开头的DOM
var names = $('[name$=with]'); //找出所有name属性值以with结尾的DOM
var icons = $('[class^="icon-"]'); //找出所有class包含至少一个以icon-开头的DOM
- 组合查找
var a = $('input[name=email]'); //只查找<input>中符合条件的
//class 同理
- 多项选择器
把多选器用,组合起来一块选。
$('p,div'); //把<p>和<div>都选出来
层级选择器
如果两个DOM元素具有层级关系,就可以使用$('ancestor descendant')来选择,层级之间用空格隔开。
<!-- HTML结构 -->
<div class="testing">
<ul class="lang">
<li class="lang-javascript">JavaScript</li>
<li class="lang-python">Python</li>
<li class="lang-lua">Lua</li>
</ul>
</div>
要选出JavaScript,可以用层级选择器:
$('ul.lang li.lang-javascript'); // [<li class="lang-javascript">JavaScript</li>]
$('div.testing li.lang-javascript'); // [<li class="lang-javascript">JavaScript</li>]
因为
- 都是
- 的祖先节点,所以上面两种方式都可以选出相应的
- 节点。
要选择所有的
- 节点,用:
$('ul.lang li');
子选择器
子选择器$('parent>child')类似层级选择器,但是限定了关系必须是父子关系。
过滤器
通常附加在选择器上帮助更精确地定位元素
$('ul.lang li'); // 选出JavaScript、Python和Lua 3个节点 $('ul.lang li:first-child'); // 仅选出JavaScript $('ul.lang li:last-child'); // 仅选出Lua $('ul.lang li:nth-child(2)'); // 选出第N个元素,N从1开始 $('ul.lang li:nth-child(even)'); // 选出序号为偶数的元素 $('ul.lang li:nth-child(odd)'); // 选出序号为奇数的元素
表单相关
针对表单元素,jQuery还有一组特殊的选择器:
- :input:可以选择< input>,< textarea>, < select>和< button>;
- :file:可以选择< input type="file">,和input[type=file]一样;
- :checkbox:可以选择复选框,和input[type=checkbox]一样;
- :radio:可以选择单选框,和input[type=radio]一样;
- :focus:可以选择当前输入焦点的元素,例如把光标放到一个< input>上,用$('input:focus')就可以选出;
- :checked:选择当前勾上的单选框和复选框,用这个选择器可以立刻获得用户选择的项目,如$('input[type=radio]:checked');
- :enabled:可以选择可以正常输入的< input>、< select> 等,也就是没有灰掉的输入;
- :disabled:和:enabled正好相反,选择那些不能输入的。
此外,jQuery还有很多有用的选择器,例如,选出可见的或隐藏的元素:
$('div:visible'); // 所有可见的div $('div:hidden'); // 所有隐藏的div
本文由 hongCYu 创作,如果您觉得本文不错,请随意赞赏
采用 知识共享署名4.0 国际许可协议进行许可
原文链接:https://hongcyu.cn/posts/javascript.html
最后更新于:2021-02-09 20:22:03

Comments | 2 条评论