对于Javascript 的学习从未停止过,奈何其水深无法想象。JS基础回顾,作为前端部分开篇内容再好不过了。 其中包括了 聊雪峰、阮一峰、方应航等大神博文,还有j《avascript 高级程序设计》 一书的内容。
夯实基础,开卷有益。
basic
script 标签又六个属性。不要用延迟脚本。
阻断式语言:解释器求值完毕之前,网页不会加载。
解释器预处理,再执行。
手机端:js内部文件可以起到性能优化。
唯一能判断NaN
的方法是通过isNaN()
函数:
1 | isNaN(NaN); // true |
String 字符串
js 中 string 属于基本数据类型 (不同于 java 中的 String)
ES6新增了一种模板字符串,表示方法和上面的多行字符串一样,但是它会自动替换字符串中的变量:
1 | var name = '小明'; |
注: 模板字符串中回车换行也算字符长度。
toString
三种方法 ToString, 其中 null
与 undefined
进行 ToString 汇报错。1
2
3
41+''
String(1)
(1).toString()
"1"
string 相关操作方法
trim()
去掉调用字符串的前后空格。substring()
返回指定索引区间的子串:
1 | var s = 'hello, world' |
concat()
拼接两个字符串并返回新的字符串。同 Array。
4.slice()
裁切,同 Array 。
repalce()
替换字符串中一个字符。
Boolean 布尔
每次看到 boolean 内心都不有的为布尔惋惜。俗话说:『老婆取得好,能够活到老啦』
ToBoolean
两种方式 ToBoolean:1
2
3Boolean('2')
!!"2"
true
五个 Falsy 值 :0,NaN,null, undefined, ''
Number 数字
ToNumber
五种方法进行 ToNumber 操作:1
2
3
4
5Number("1")
parseInt('1',10) // 第二个参数表示10进制
parseFloat('1.2')
"1" - 0
+ "1" // 取正
Object 对象
ToObject
访问属性是通过.
操作符完成的,但这要求属性名必须是一个有效的变量名。如果属性名包含特殊字符,就必须用''
括起来:
1 | var xiaohong = { |
xiaohong
的属性名middle-school
不是一个有效的变量,就需要用''
括起来。访问这个属性也无法使用.
操作符,必须用['xxx']
来访问:
1 | xiaohong['middle-school']; // 'No.1 Middle School' |
也可以用xiaohong['name']
来访问xiaohong
的name
属性,不过xiaohong.name
的写法更简洁。我们在编写JavaScript代码的时候,属性名尽量使用标准的变量名,这样就可以直接通过object.prop
的形式访问一个属性了。
实际上JavaScript对象的所有属性都是字符串,不过属性对应的值可以是任意数据类型。
要判断一个属性是否是xiaoming
自身拥有的,而不是继承得到的,可以用hasOwnProperty()
方法:
1 | var xiaoming = { |
for
循环的一个变体是for ... in
循环,它可以把一个对象的所有属性依次循环出来:
1 | var o = { |
要过滤掉对象继承的属性,用hasOwnProperty()
来实现:
1 | var o = { |
由于Array
也是对象,而它的每个元素的索引被视为对象的属性,因此,for ... in
循环可以直接循环出Array
的索引:
1 | var a = ['A', 'B', 'C']; |
请注意,for ... in
对Array
的循环得到的是String
而不是Number
。
set map……..
遍历Array
可以采用下标循环,遍历Map
和Set
就无法使用下标。为了统一集合类型,ES6标准引入了新的iterable
类型,Array
、Map
和Set
都属于iterable
类型。
具有iterable
类型的集合可以通过新的for ... of
循环来遍历。
注意区别 for in。 for in 不完善,仅限于对象输出。
然而,更好的方式是直接使用iterable
内置的forEach
方法,它接收一个函数,每次迭代就自动回调该函数。以Array
为例:1
2
3
4
5
6
7var a = ['A', 'B', 'C'];
a.forEach(function (element, index, array) {
// element: 指向当前元素的值
// index: 指向当前索引
// array: 指向Array对象本身
console.log(element + ', index = ' + index);
});
如果对某些参数不感兴趣,由于JavaScript的函数调用不要求参数必须一致,因此可以忽略它们。例如,只需要获得Array
的element
:
1 | var a = ['A', 'B', 'C']; |
function
arguments
最常用于判断传入参数的个数。你可能会看到这样的写法:
1 | // foo(a[, b], c) |
ES6标准引入了rest参数,用于接收未定义的多余参数:
1 | function foo(a, b, ...rest) { |
作用域
自定义全局作用域:
减少冲突的一个方法是把自己的所有变量和函数全部绑定到一个全局变量中。例如:
1 | // 唯一的全局变量MYAPP: |
把自己的代码全部放入唯一的名字空间MYAPP
中,会大大减少全局变量冲突的可能。
许多著名的JavaScript库都是这么干的:jQuery,YUI,underscore等等。
let
let 的作用:
由于JavaScript的变量作用域实际上是函数内部,我们在for
循环等语句块中是无法定义具有局部作用域的变量的:
1 | 'use strict'; |
为了解决块级作用域,ES6引入了新的关键字let
,用let
替代var
可以申明一个块级作用域的变量:
1 | 'use strict'; |
解构赋值1
2
3~~~
var [x, y, z] = ['hello', 'JavaScript', 'ES6'];
~~~
从一个对象中取出若干属性,也可以使用解构赋值,便于快速获取对象的指定属性:
1 |
|
使用解构赋值对对象属性进行赋值时,如果对应的属性不存在,变量将被赋值为undefined
,这和引用一个不存在的属性获得undefined
是一致的。如果要使用的变量名和属性名不一致,可以用下面的语法获取:
1 | var person = { |
这是因为JavaScript引擎把{
开头的语句当作了块处理,于是=
不再合法。解决方法是用小括号括起来:
1 | ({x, y} = { name: '小明', x: 100, y: 200}); |
快速获取当前页面的域名和路径:
1 | var {hostname:domain, pathname:path} = location; // 重命名爲domain |
如果一个函数接收一个对象作为参数,那么,可以使用解构直接把对象的属性绑定到变量中。例如,下面的函数可以快速创建一个Date
对象:
1 | function buildDate({year, month, day, hour=0, minute=0, second=0}) { |
它的方便之处在于传入的对象只需要year
、month
和day
这三个属性:
1 | buildDate({ year: 2017, month: 1, day: 1 }); |
也可以传入hour
、minute
和second
属性:
1 | buildDate({ year: 2017, month: 1, day: 1, hour: 20, minute: 15 }); |
this
用一个that
变量首先捕获this
:
用var that = this;
,你就可以放心地在方法内部定义其他函数,而不是把所有语句都堆到一个方法中。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16'use strict';
var xiaoming = {
name: '小明',
birth: 1990,
age: function () {
var that = this; // 在方法内部一开始就捕获this
function getAgeFromBirth() {
var y = new Date().getFullYear();
return y - that.birth; // 用that而不是this
}
return getAgeFromBirth();
}
};
xiaoming.age(); // 25
arr.map() arr.reduce()
map()
、reduce
、filter()
、sort()
、every()、find()、findIndex()、forEach()、
、
closure
返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
obj
总结一下,有这么几条规则需要遵守:
不要使用
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'
。
number
对象调用toString()
报SyntaxError:
1 | 123.toString(); // SyntaxError |
遇到这种情况,要特殊处理一下:
1 | 123..toString(); // '123', 注意是两个点! |
JavaScript的Date对象月份值从0开始,牢记0=1月,1=2月,2=3月,……,11=12月。
regExp
无法识别连续的空格,用正则表达式试试:
1 | 'a b c'.split(/\s+/); // ['a', 'b', 'c'] |
jason
统一解析,JSON的字符串规定必须用双引号""
,Object的键也必须用双引号""
对象序列化成JSON格式的字符串:
1 | 'use strict'; |
要输出得好看一些,可以加上参数,按缩进输出:
1 | JSON.stringify(xiaoming, null, ' '); |
第二个参数用于控制如何筛选对象的键值,如果我们只想输出指定的属性,可以传入Array
:
1 | JSON.stringify(xiaoming, ['name', 'skills'], ' '); |
结果:
1 | { |
反序列化
拿到一个JSON格式的字符串,我们直接用JSON.parse()
把它变成一个JavaScript对象:
1 | JSON.parse('[1,2,3,true]'); // [1, 2, 3, true] |
JSON.parse()
还可以接收一个函数,用来转换解析出的属性:
1 | 'use strict'; |
DOM
js 最重要的任务是找到 DOM 上的 element,然后负责添加 css效果类。
选择器
集合选择器1
document.querySelectorAll('\[data-x\]')
元素选择器1
document.querySelector('a\[href="#'+ id +'"\]').parentNode