(一)字符串
1.indexOf 返回字符串出现的位置,没有找到指定的字符串则返回-1
2.substring(尽管 String.prototype.substr(…)
没有严格被废弃 (as in "removed from the Web standards"), 但它被认作是遗留的函数并且可以的话应该避免使用,一般用substring这个代替)
var s = 'hello, world'
s.substring(0, 5); // 从索引0开始到5(不包括5),返回'hello'
s.substring(7); // 从索引7开始到结束,返回'world'
3.slice 提取一个字符串的一部分,并返回一新的字符串 ,截取方法和substring一样
(二)数组
1.indexOf 返回指定的元素的位置 ,没有找到指定的元素则返回-1
2.slice()
就是对应String的substring()
版本,它截取Array
的部分元素,然后返回一个新的Array
如果不给slice()
传递任何参数,它就会从头到尾截取所有元素。利用这一点,我们可以很容易地复制一个Array
var arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
arr.slice(0, 3); // 从索引0开始,到索引3结束,但不包括索引3: ['A', 'B', 'C']
arr.slice(3); // 从索引3开始到结束: ['D', 'E', 'F', 'G']
3.数组的一些操作方法
push和pop,
unshift和shift(unshift往Array
的头部添加若干元素,shift
方法则把Array
的第一个元素删掉) ,
sort(sort()
可以对当前Array
进行排序),
reverse(reverse()
把整个Array
的元素反转),
array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
var arr = ['Microsoft', 'Apple', 'Yahoo', 'AOL', 'Excite', 'Oracle'];
// 从索引2开始删除3个元素,然后再添加两个元素:
arr.splice(2, 3, 'Google', 'Facebook'); // 返回删除的元素 ['Yahoo', 'AOL', 'Excite']
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
// 只删除,不添加:
arr.splice(2, 2); // ['Google', 'Facebook']
arr; // ['Microsoft', 'Apple', 'Oracle']
// 只添加,不删除:
arr.splice(2, 0, 'Google', 'Facebook'); // 返回[],因为没有删除任何元素
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
concat(concat()
方法把当前的Array
和另一个Array
连接起来,并返回一个新的Array,
实际上,concat()
方法可以接收任意个元素和Array
,并且自动把Array
拆开,然后全部添加到新的Array
里)
var arr = ['A', 'B', 'C'];
arr.concat(1, 2, [3, 4]); // ['A', 'B', 'C', 1, 2, 3, 4]
join(它把当前Array
的每个元素都用指定的字符串连接起来,然后返回连接后的字符串)
多维数组:
如果数组的某个元素又是一个Array
,则可以形成多维数组
(三)对象
1.检测对象是否拥有某一个属性用in运算符(in
判断一个属性存在,这个属性不一定是xiaoming
的,它可能是xiaoming
继承得到的,要判断一个属性是否是xiaoming
自身拥有的,而不是继承得到的,可以用hasOwnProperty()
方法)
var xiaoming = {
name: '小明'
};
xiaoming.hasOwnProperty('name'); // true
xiaoming.hasOwnProperty('toString'); // false
(四)条件判断
1.JavaScript把null
、undefined
、0
、NaN
和空字符串''
视为false
,其他值一概视为true
(五)循环
1.for ... in
循环,它可以把一个对象的所有属性依次循环出来 (推荐在循环对象属性的时候,使用for...in
,在遍历数组的时候的时候使用for...of
)
var o = {
name: 'Jack',
age: 20,
city: 'Beijing'
};
for (var key in o) {
console.log(key); // 'name', 'age', 'city'
}
(六)函数
1.if条件语句中!=是两个=号吗,!==是三个等号的不等于吗?
全局变量会绑定到window
上,不同的JavaScript文件如果使用了相同的全局变量,或者定义了相同名字的顶层函数,都会造成命名冲突,并且很难被发现。
减少冲突的一个方法是把自己的所有变量和函数全部绑定到一个全局变量中
// 唯一的全局变量MYAPP:
var MYAPP = {};
// 其他变量:
MYAPP.name = 'myapp';
MYAPP.version = 1.0;
// 其他函数:
MYAPP.foo = function () {
return 'foo';
};
2.apply
要指定函数的this
指向哪个对象,可以用函数本身的apply
方法,它接收两个参数,第一个参数就是需要绑定的this
变量,第二个参数是Array
,表示函数本身的参数。
getAge.apply(xiaoming, []); // 25, this指向xiaoming, 参数为空
另一个与apply()
类似的方法是call()
,唯一区别是:
-
apply()
把参数打包成Array
再传入; -
call()
把参数按顺序传入。
比如调用Math.max(3, 5, 4)
,分别用apply()
和call()
实现如下:
Math.max.apply(null, [3, 5, 4]); // 5
Math.max.call(null, 3, 5, 4); // 5
对普通函数调用,我们通常把this
绑定为null
。
(七)高阶函数(一个函数接收另一个函数作为参数,这种函数就称之为高阶函数。)
1.map(),
传入的参数是一个函数,
reduce(),Array的reduce()
把一个函数作用在这个Array
的[x1, x2, x3...]
上,这个函数必须接收两个参数,reduce()
把结果继续和序列的下一个元素做累积计算
filter也是一个常用的操作,它用于把Array
的某些元素过滤掉,然后返回剩下的元素
sort()
方法默认把所有元素先转换为String再排序,结果'10'
排在了'2'
的前面,因为字符'1'
比字符'2'
的ASCII码小,对于两个元素x
和y
,如果认为x < y
,则返回-1
,如果认为x == y
,则返回0
,如果认为x > y
,则返回1
,这样,排序算法就不用关心具体的比较过程,而是根据比较结果直接排序
[10, 20, 1, 2].sort(); // [1, 10, 2, 20]
every()
方法可以判断数组的所有元素是否满足测试条件
find()
方法用于查找符合条件的第一个元素,如果找到了,返回这个元素,否则,返回undefined
findIndex()
和find()
类似,也是查找符合条件的第一个元素,不同之处在于findIndex()
会返回这个元素的索引,如果没有找到,返回-1
forEach()
和map()
类似,它也把每个元素依次作用于传入的函数,但不会返回新的数组。forEach()
常用于遍历数组,因此,传入的函数不需要返回值
(八)标准对象
1.Date
Date.now(),功能和getTime()一样,表示当前时间与起始时间之间的毫秒数。
Date.parse()也是时间戳吗?
2.RegExp
RegExp对象的test()
方法用于测试给定的字符串是否符合条件
var re = /^\d{3}\-\d{3,8}$/;
re.test('010-12345'); // true
re.test('010-1234x'); // false
re.test('010 12345'); // false
RegExp
对象上用exec()
方法提取出子串来。
exec()
方法在匹配成功后,会返回一个Array
,第一个元素是正则表达式匹配到的整个字符串,后面的字符串表示匹配成功的子串。
exec()
方法在匹配失败时返回null
。
3.json
1.在JSON中,一共就这么几种数据类型:
- number:和JavaScript的
number
完全一致; - boolean:就是JavaScript的
true
或false
; - string:就是JavaScript的
string
; - null:就是JavaScript的
null
; - array:就是JavaScript的
Array
表示方式——[]
; - object:就是JavaScript的
{ ... }
表示方式。
为了统一解析,JSON的字符串规定必须用双引号""
,Object的键也必须用双引号""
把任何JavaScript对象变成JSON,就是把这个对象序列化成一个JSON格式的字符串,这样才能够通过网络传递给其他计算机。
如果我们收到一个JSON格式的字符串,只需要把它反序列化成一个JavaScript对象,就可以在JavaScript中直接使用这个对象了。
2.序列化
JSON.stringify(value[, replacer [, space]])
value
:将要序列化成 一个JSON 字符串的值。
replacer
:如果该参数是一个函数,则在序列化过程中,被序列化的值的每个属性都会经过该函数的转换和处理;如果该参数是一个数组,则只有包含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中;如果该参数为null或者未提供,则对象所有的属性都会被序列化
space
:指定缩进用的空白字符串,用于美化输出(pretty-print);如果参数是个数字,它代表有多少的空格;上限为10。该值若小于1,则意味着没有空格;如果该参数为字符串(字符串的前十个字母),该字符串将被作为空格;如果该参数没有提供(或者为null)将没有空格。
如果我们还想要精确控制如何序列化小明,可以给xiaoming
定义一个toJSON()
的方法,直接返回JSON应该序列化的数据
var xiaoming = {
name: '小明',
age: 14,
gender: true,
height: 1.65,
grade: null,
'middle-school': '\"W3C\" Middle School',
skills: ['JavaScript', 'Java', 'Python', 'Lisp'],
toJSON: function () {
return { // 只输出name和age,并且改变了key:
'Name': this.name,
'Age': this.age
};
}
};
JSON.stringify(xiaoming); // '{"Name":"小明","Age":14}'
3.反序列化
JSON.parse(text [,reviver ])
reviver:如果是一个函数,这就规定了在返回之前如何转换最初通过解析生成的值
(九)面向对象编程
1.原型继承
JavaScript不区分类和实例的概念,而是通过原型(prototype)来实现面向对象编程
var Student = {
name: 'Robot',
height: 1.2,
run: function () {
console.log(this.name + ' is running...');
}
};
var xiaoming = {
name: '小明'
};
xiaoming.__proto__ = Student;
不过我们一般不会直接用obj.__proto__
去改变一个对象的原型,而是用Object.create()
方法传入一个原型对象
// 原型对象:
var Student = {
name: 'Robot',
height: 1.2,
run: function () {
console.log(this.name + ' is running...');
}
};
function createStudent(name) {
// 基于Student原型创建一个新对象:
var s = Object.create(Student);
// 初始化新对象:
s.name = name;
return s;
}
var xiaoming = createStudent('小明');
xiaoming.run(); // 小明 is running...
xiaoming.__proto__ === Student; // true
JavaScript的原型继承实现方式就是:
-
定义新的构造函数,并在内部用
call()
调用希望“继承”的构造函数,并绑定this
; -
借助中间函数
F
实现原型链继承,最好通过封装的inherits
函数完成; -
继续在新的构造函数的原型上定义新方法。
2.class继承
class Student {
constructor(name) {
this.name = name;
}
hello() {
alert('Hello, ' + this.name + '!');
}
}
class PrimaryStudent extends Student {
constructor(name, grade) {
super(name); // 记得用super调用父类的构造方法!
this.grade = grade;
}
myGrade() {
alert('I am at grade ' + this.grade);
}
}
(十)浏览器对象
1.window
innerWidth
,innerHeight,outerWidth
,outerHeight
2.navigator
- navigator.appName:浏览器名称;
- navigator.appVersion:浏览器版本;
- navigator.language:浏览器设置的语言;
- navigator.platform:操作系统类型;
- navigator.userAgent:浏览器设定的
User-Agent
字符串。
3.screen(screen
对象表示屏幕的信息)
- screen.width:屏幕宽度,以像素为单位;
- screen.height:屏幕高度,以像素为单位;
- screen.colorDepth:返回颜色位数,如8、16、24。
4.location(表示当前页面的URL信息)
location.assign()(要加载一个新页面)
location.reload()(重新加载当前页面)
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'
5.document
document
对象表示当前页面。由于HTML在浏览器中以DOM形式表示为树形结构,document
对象就是整个DOM树的根节点document
的title
属性是从HTML文档中的<title>xxx</title>
读取的
document.getElementById('drink-menu')
document.cookie(服务器在设置Cookie时可以使用httpOnly
,设定了httpOnly
的Cookie将不能被JavaScript读取)
6.history(基本不使用)
history
对象保存了浏览器的历史记录,JavaScript可以调用history
对象的back()
或forward ()
,相当于用户点击了浏览器的“后退”或“前进”按钮
(十一)操纵dom
1.插入DOM
appendChild(会把一个子节点添加到父节点的最后一个子节点)
insertBefore(使用parentElement.insertBefore(newElement, referenceElement);
,子节点会插入到referenceElement
之前)
removeChild(删除dom)
2.表单
隐藏文本,对应的<input type="hidden">
,用户不可见,但表单提交时会把隐藏文本发送到服务器
对于单选框和复选框用checked判断被选中的值
HTML5新增了大量标准控件,常用的包括date
、datetime
、datetime-local
、color
等,它们都使用<input>
标签
在form表单提交时没有name
属性的<input>
的数据不会被提交。
3.ajax请求
跨域(参见我的文章前端跨域的几种解决办法)
jsonp,cors,nginx反向代理
4.promise
Promise.race()(有些时候,多个异步任务是为了容错。比如,同时向两个URL读取用户的个人信息,只需要获得先返回的结果即可)
var p1 = new Promise(function (resolve, reject) {
setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 600, 'P2');
});
Promise.race([p1, p2]).then(function (result) {
console.log(result); // 'P1'
});
5.Canvas
用canvas.getContext
来测试浏览器是否支持Canvas
(十二)jquery
1. noConflict() (释放 jQuery 对 $ 变量的控制。)
2.jQuery对象类似于数组
jQuery对象和DOM对象之间可以互相转化
var div = $('#abc'); // jQuery对象
var divDom = div.get(0); // 假设存在div,获取第1个DOM元素
var another = $(divDom); // 重新把DOM包装为jQuery对象
3.选择器
1.按class查找
<div class="red green">...</div>
var a = $('.red.green'); // 注意没有空格!
没有空格表示该元素上有两个class,有空格的是层级选择器
2.按属性查找
$("[id]")
var email = $('[name=email]'); // 找出<??? name="email">
var passwordInput = $('[type=password]'); // 找出<??? type="password">
var a = $('[items="A B"]'); // 找出<??? items="A B">
按属性查找还可以使用前缀查找或者后缀查找,这个方法尤其适合通过class属性查找,且不受class包含多个名称的影响
var icons = $('[class^="icon-"]'); // 找出所有class包含至少一个以`icon-`开头的DOM
// 例如: class="icon-clock", class="abc icon-home"
3.多项选择器
多项选择器就是把多个选择器用,
组合起来一块选
$('p,div'); // 把<p>和<div>都选出来
$('p.red,p.green'); // 把<p class="red">和<p class="green">都选出来
4.层级选择器
层级之间用空格隔开
5.子选择器
子选择器$('parent>child')
类似层级选择器,但是限定了层级关系必须是父子关系,就是<child>
节点必须是<parent>
节点的直属子节点
6.过滤器
过滤器一般不单独使用,它通常附加在选择器上,帮助我们更精确地定位元素
$('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)'); // 选出序号为奇数的元素
7.表单相关
-
: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
正好相反,选择那些不能输入的。
8.查找
下列元素本身又接收一个任意的选择器
find()(某个节点的所有子节点中查找)
parent()(从当前节点开始向上查找)
next()
和prev()(
对于位于同一层级的节)
9. 过滤
filter()
var langs = $('ul.lang li'); // 拿到JavaScript, Python, Swift, Scheme和Haskell
var a = langs.filter('.dy'); // 拿到JavaScript, Python, Scheme
或者传入一个函数,要特别注意函数内部的this
被绑定为DOM对象,不是jQuery对象
var langs = $('ul.lang li'); // 拿到JavaScript, Python, Swift, Scheme和Haskell
langs.filter(function () {
return this.innerHTML.indexOf('S') === 0; // 返回S开头的节点
}); // 拿到Swift, Scheme