目录
数据类型
基本(值)类型
String: 任意字符串
Number: 任意的数字
boolean: true/false
undefined: undefined
null: null
对象(引用)类型
Object: 任意对象
Function: 一种特别的对象(可以执行)
Array: 一种特别的对象(数值下标, 内部数据是有序的)
判断
typeof:
可以判断: undefined/ 数值 / 字符串 / 布尔值 / function
不能判断: null与object object与array
console.log(typeof null); //Object
console.log(typeof Array); //function
console.log(typeof Object); //function
instanceof: 判断对象的具体类型
=== 可以判断: undefined, null
undefined==null true,
undefined=== null false
数组常用方法
join() 方法也可将所有数组元素结合为一个字符串。它的行为类似 toString(),但是还可以规定分隔符
var str = ["a", "b", "c", "d"];
let s = str.join("*"); //a*b*c*d
pop() 方法从数组中删除最后一个元素,pop() 方法返回“被删除”的值。
push() 方法(在数组结尾处)向数组添加一个新的元素,push() 方法返回新数组的长度。
shift() 方法会删除首个数组元素,shift() 方法返回被“位移出”的字符串。
unshift() 方法(在开头)向数组添加新元素,unshift() 方法返回新数组的长度。
delete 会在数组留下未定义的空洞。请使用 pop() 或 shift() 取而代之。
slice() 方法用数组的某个片段切出新数组
slice() 可接受两个参数,比如 (1, 3)。
如果结束参数被省略,则 slice() 会切出数组的剩余部分
该方法会从开始参数选取元素,直到结束参数(不包括)为止。
var str = ["a", "b", "c", "d", "e"]; var arr = str.slice(1,3); console.log(arr) //b,c
splice(a,b,c,d,e) 方法可用于向数组添加新项,
第一个参数(2)定义了应添加新元素的位置(拼接)。
第二个参数(0)定义应删除多少元素。
其余参数(c,d,e)定义要添加的新元素
var str = ["a", "b", "c", "d","e"]; str.splice(2, 0, "x", "y"); console.log(str) //a,b,x,y,c,d,e
concat() 方法通过合并(连接)现有数组来创建一个新数组,不改变原数组。
var str1 = ["a", "b"];
var str2 = ["c", "d", "e"];
var str = str1.concat(str2);
console.log(str) //a,b,c,d,e
reverse() 方法反转数组中的元素。会给变原数组
sort() 函数按照字符串顺序对值进行排序。如果数字按照字符串来排序,则 "25" 大于 "100",因为 "2" 大于 "1"。。通过一个比值函数来修正此问题
var points = [40, 100, 1, 5, 25, 10];
points.sort(function(a, b){return a - b});
比较函数应该返回一个负,零或正值,这取决于参数:
function(a, b){return a-b}
当比较 40 和 100 时,sort() 方法会调用比较函数 function(40,100)。
该函数计算 40-100,然后返回 -60(负值)。
排序函数将把 40 排序为比 100 更低的值。以随机顺序排序数组
var points = [40, 100, 1, 5, 25, 10]; points.sort(function(a, b){return 0.5 - Math.random()});
数组迭代方法
Array.forEach()
forEach() 方法为每个数组元素调用一次函数(回调函数)
接受 3 个参数:元素值,索引,数组本身
Array.map()
map() 方法通过对每个数组元素执行函数来创建新数组。
map() 方法不会对没有值的数组元素执行函数。
map() 方法不会更改原始数组。
有 3 个参数:元素值,索引,数组本身
Array.filter()
过滤函数
var num = [45, 4, 9, 16, 25];
var arr = num.filter(value=>value > 18)
console.log(arr) //45,25
filter()
方法还可以接受第二个参数,用来绑定参数函数内部的this
变量。
var obj = { MAX: 3 };
var myFilter = function (item) {
if (item > this.MAX) return true;
};
var arr = [2, 8, 3, 4, 1, 3, 2, 9];
arr.filter(myFilter, obj) // [8, 4, 9]
上面代码中,过滤器myFilter()
内部有this
变量,它可以被filter()
方法的第二个参数obj
绑定,返回大于3
的成员。
链式调用
var users = [
{name: 'tom', email: '[email protected]'},
{name: 'peter', email: '[email protected]'}
];
users
.map(function (user) {
return user.email;
})
.filter(function (email) {
return /^t/.test(email);
})
.forEach(function (email) {
console.log(email);
});
// "[email protected]"
Array.reduce()
reduce() 方法在每个数组元素上运行函数,以生成(减少它)单个值。
reduce() 方法在数组中从左到右工作。
reduce() 方法不会减少原始数组。
var numbers = [1, 2, 3, 4, 5];
var sum = numbers.reduce((total, value, index, array)=>{
return total + value;
},0);
console.log(sum) //15
可接受 4 个参数:初始值/先前返回的值,元素值,索引,数组本身
Array.reduceRight()
reduceRight() 方法在每个数组元素上运行函数,以生成(减少它)单个值。
reduceRight() 方法在数组中从右到左工作。
reduceRight() 方法不会减少原始数组。
和Array.reduce()不同的就是工作方式
Array.every()
every() 方法检查所有数组值是否通过测试。
Array.some()
some() 方法检查某些数组值是否通过了测试。
Array.indexOf()
indexOf() 方法在数组中搜索元素值并返回其位置。
Array.indexOf(item, start)
如果未找到项目,Array.indexOf() 返回 -1。 如果项目多次出现,则返回第一次出现的位置。 |
Array.lastIndexOf()
Array.lastIndexOf() 与 Array.indexOf() 类似,但是从数组结尾开始搜索。
Array.lastIndexOf(item, start)
item | 必需。要检索的项目。 |
start | 可选。从哪里开始搜索。负值将从结尾开始的给定位置开始,并搜索到开头。 |
Array.find()
find() 方法返回通过测试函数的第一个数组元素的值。
Date对象方法
方法 | 描述 |
---|---|
Date() | 返回当日的日期和时间。 |
getDate() | 从 Date 对象返回一个月中的某一天 (1 ~ 31)。 |
getDay() | 从 Date 对象返回一周中的某一天 (0 ~ 6)。 |
getMonth() | 从 Date 对象返回月份 (0 ~ 11)。 |
getFullYear() | 从 Date 对象以四位数字返回年份。 |
getYear() | 请使用 getFullYear() 方法代替。 |
getHours() | 返回 Date 对象的小时 (0 ~ 23)。 |
getMinutes() | 返回 Date 对象的分钟 (0 ~ 59)。 |
getSeconds() | 返回 Date 对象的秒数 (0 ~ 59)。 |
getMilliseconds() | 返回 Date 对象的毫秒(0 ~ 999)。 |
getTime() | 返回 1970 年 1 月 1 日至今的毫秒数。 |
parse() | 返回1970年1月1日午夜到指定日期(字符串)的毫秒数。 |
setDate() | 设置 Date 对象中月的某一天 (1 ~ 31)。 |
setMonth() | 设置 Date 对象中月份 (0 ~ 11)。 |
setFullYear() | 设置 Date 对象中的年份(四位数字)。 |
setYear() | 请使用 setFullYear() 方法代替。 |
setHours() | 设置 Date 对象中的小时 (0 ~ 23)。 |
setMinutes() | 设置 Date 对象中的分钟 (0 ~ 59)。 |
setSeconds() | 设置 Date 对象中的秒钟 (0 ~ 59)。 |
setMilliseconds() | 设置 Date 对象中的毫秒 (0 ~ 999)。 |
setTime() | 以毫秒设置 Date 对象。 |
toSource() | 返回该对象的源代码。 |
toString() | 把 Date 对象转换为字符串。 |
toTimeString() | 把 Date 对象的时间部分转换为字符串。 |
toDateString() | 把 Date 对象的日期部分转换为字符串。 |
toGMTString() | 请使用 toUTCString() 方法代替。 |
toLocaleString() | 根据本地时间格式,把 Date 对象转换为字符串。 |
toLocaleTimeString() | 根据本地时间格式,把 Date 对象的时间部分转换为字符串。 |
toLocaleDateString() | 根据本地时间格式,把 Date 对象的日期部分转换为字符串。 |
valueOf() | 返回 Date 对象的原始值。 |
Math 对象方法
方法 | 描述 |
---|---|
abs(x) | 返回 x 的绝对值 |
acos(x) | 返回 x 的反余弦值,以弧度计 |
asin(x) | 返回 x 的反正弦值,以弧度计 |
atan(x) | 以介于 -PI/2 与 PI/2 弧度之间的数值来返回 x 的反正切值。 |
atan2(y,x) | 返回从 x 轴到点 (x,y) 的角度 |
ceil(x) | 对 x 进行上舍入 |
cos(x) | 返回 x 的余弦 |
exp(x) | 返回 Ex 的值 |
floor(x) | 对 x 进行下舍入 |
log(x) | 返回 x 的自然对数(底为e) |
max(x,y,z,...,n) | 返回最高值 |
min(x,y,z,...,n) | 返回最低值 |
pow(x,y) | 返回 x 的 y 次幂 |
random() | 返回 0 ~ 1 之间的随机数 |
round(x) | 把 x 四舍五入为最接近的整数 |
sin(x) | 返回 x(x 以角度计)的正弦 |
sqrt(x) | 返回 x 的平方根 |
tan(x) | 返回角的正切 |
正则表达式
match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。
该方法类似 indexOf() 和 lastIndexOf(),但是它返回指定的值,而不是字符串的位置。
stringObject.match(searchvalue) stringObject.match(regexp)
参数 | 描述 |
---|---|
searchvalue | 必需。规定要检索的字符串值。 |
regexp | 必需。规定要匹配的模式的 RegExp 对象。如果该参数不是 RegExp 对象,则需要首先把它传递给 RegExp 构造函数,将其转换为 RegExp 对象。 |
在字符串方法 search() 、replace() 中使用正则表达式
var regex = new RegExp('xyz', 'i');
// 等价于
var regex = /xyz/i;
----------------------------------
var regex = new RegExp(/xyz/i);
// 等价于
var regex = /xyz/i;
var str = "Visit W3School";
var n = str.search(/w3school/i); //n=6
----------------------------------------
var str = "Hello XiaoSa!";
var res = str.replace(/xiaosa/i, "潇洒"); //Hello 潇洒
正则表达式中,需要反斜杠转义的,一共有12个字符:^
、.
、[
、$
、(
、)
、|
、*
、+
、?、{和\。需要特别注意的是,如果使用RegExp
方法生成正则对象,转义需要使用两个斜杠,因为字符串内部会先转义一次。
修饰符 | 描述 |
---|---|
i | 执行对大小写不敏感的匹配。 |
g | 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。 |
m | 执行多行匹配。 |
元字符 | 描述 |
---|---|
. | 查找单个字符,除了换行和行结束符。 |
\w | 查找单词字符。 |
\W | 查找非单词字符。 |
\d | 查找数字。 |
\D | 查找非数字字符。 |
\s | 查找空白字符。 |
\S | 查找非空白字符。 |
\b | 匹配单词边界。 |
\B | 匹配非单词边界。 |
\0 | 查找 NUL 字符。 |
\n | 查找换行符。 |
\f | 查找换页符。 |
\r | 查找回车符。 |
\t | 查找制表符。 |
\v | 查找垂直制表符。 |
\xxx | 查找以八进制数 xxx 规定的字符。 |
\xdd | 查找以十六进制数 dd 规定的字符。 |
\uxxxx | 查找以十六进制数 xxxx 规定的 Unicode 字符。 |
量词 | 描述 |
---|---|
n+ | 匹配任何包含至少一个 n 的字符串。 |
n* | 匹配任何包含零个或多个 n 的字符串。 |
n? | 匹配任何包含零个或一个 n 的字符串。 |
n{X} | 匹配包含 X 个 n 的序列的字符串。 |
n{X,Y} | 匹配包含 X 至 Y 个 n 的序列的字符串。 |
n{X,} | 匹配包含至少 X 个 n 的序列的字符串。 |
n$ | 匹配任何结尾为 n 的字符串。 |
^n | 匹配任何开头为 n 的字符串。 |
?=n | 匹配任何其后紧接指定字符串 n 的字符串。 |
?!n | 匹配任何其后没有紧接指定字符串 n 的字符串。 |
js较难语句标识
语句 | 描述 |
---|---|
class | 声明类。 |
continue | 如果出现指定条件,则(在循环中)中断一次循环,并继续循环中的下一次迭代。 |
debugger | 停止执行 JavaScript,并调用调试功能(如果有)。 |
for ... in | 循环遍历对象的属性。 |
for ... of | 循环遍历可迭代对象的值。 |
throw | 抛出(生成)错误。 |
try ... catch ... finally | 标记在 try 块中发生错误时要执行的语句块,并实现错误处理。 |
this 关键词
this 关键词指的是它所属的对象
- 在方法中,this 指的是所有者对象。
- 单独的情况下,this 指的是全局对象。
- 在函数中,this 指的是全局对象。
- 在函数中,严格模式下,this 是 undefined。
- 在事件中,this 指的是接收事件的元素。
下面这几种用法,都会改变this
的指向。
// 情况一
(obj.foo = obj.foo)() // window
// 情况二
(false || obj.foo)() // window
// 情况三
(1, obj.foo)() // window
上面代码中,
obj.foo
就是一个值。这个值真正调用的时候,运行环境已经不是obj
了,而是全局环境,所以this
不再指向obj
。可以这样理解,JavaScript 引擎内部,
obj
和obj.foo
储存在两个内存地址,称为地址一和地址二。obj.foo()
这样调用时,是从地址一调用地址二,因此地址二的运行环境是地址一,this
指向obj
。但是,上面三种情况,都是直接取出地址二进行调用,这样的话,运行环境就是全局环境,因此this
指向全局环境。
避免多层 this
var o = {
f1: function () {
console.log(this);
var f2 = function () {
console.log(this);
}();
}
}
o.f1()
// Object
// Window
上面代码包含两层this
,结果运行后,第一层指向对象o
,第二层指向全局对象,因为实际执行的是下面的代码。
var temp = function () {
console.log(this);
};
var o = {
f1: function () {
console.log(this);
var f2 = temp();
}
}
一个解决方法是在第二层改用一个指向外层this
的变量。
var o = {
f1: function() {
console.log(this);
var _this = this;
var f2 = function() {
console.log(_this );
}();
}
}
o.f1()
// Object
// Object
上面代码定义了变量_this
,固定指向外层的this
,然后在内层使用_this
,就不会发生this
指向的改变。
避免数组处理方法中的 this
数组的map
和foreach
方法,允许提供一个函数作为参数。这个函数内部不应该使用this
。
var o = {
v: 'hello',
p: [ 'a1', 'a2' ],
f: function f() {
this.p.forEach(function (item) {
console.log(this.v + ' ' + item);
});
}
}
o.f()
// undefined a1
// undefined a2
上面代码中,
foreach
方法的回调函数中的this
,其实是指向window
对象,因此取不到o.v
的值。原因跟上一段的多层this
是一样的,就是内层的this
不指向外部,而指向顶层对象。解决这个问题的一种方法,就是前面提到的,使用中间变量固定
this
。(不再赘述)另一种方法是将
this
当作foreach
方法的第二个参数,固定它的运行环境。
var o = {
v: 'hello',
p: [ 'a1', 'a2' ],
f: function f() {
this.p.forEach(function (item) {
console.log(this.v + ' ' + item);
}, this);
}
}
o.f()
// hello a1
// hello a2
绑定 this 的方法
JavaScript 提供了call
、apply
、bind
这三个方法,来切换/固定this
的指向。
call() 和 apply() 这样的方法可以将 this 引用到任何对象。
var obj = {};
var f = function () {
return this;
};
f() === window // true
f.call(obj) === obj // true
全局环境运行函数
f
时,this
指向全局环境(浏览器为window
对象);call方法可以改变this
的指向,指定this
指向对象obj
,然后在对象obj
的作用域中运行函数f。
call方法的参数,应该是一个对象。如果参数为空、null
和undefined
,则默认传入全局对象。
call
方法的一个应用是调用对象的原生方法。
var obj = {};
obj.hasOwnProperty('toString') // false
// 覆盖掉继承的 hasOwnProperty 方法
obj.hasOwnProperty = function () {
return true;
};
obj.hasOwnProperty('toString') // true
Object.prototype.hasOwnProperty.call(obj, 'toString') // false
上面代码中,
hasOwnProperty
是obj
对象继承的方法,如果这个方法一旦被覆盖,就不会得到正确结果。call
方法可以解决这个问题,它将hasOwnProperty
方法的原始定义放到obj
对象上执行,这样无论obj
上有没有同名方法,都不会影响结果。
call() 和 apply() 之间的区别
不同之处是:
call() 方法分别接受参数。
apply() 方法接受数组形式的参数。
JavaScript 不提供找出数组最大元素的函数。结合使用apply
方法和Math.max
方法,就可以返回数组的最大元素。
var a = [10, 2, 4, 15, 9];
Math.max.apply(null, a) // 15
--------------------------
Math.max(...a) //15
将数组的空元素变为undefined
Array.apply(null, ['a', ,'b'])
// [ 'a', undefined, 'b' ]
空元素与
undefined
的差别在于,数组的forEach
方法会跳过空元素,但是不会跳过undefined
。因此,遍历内部元素的时候,会得到不同的结果。
var a = ['a', , 'b'];
function print(i) {
console.log(i);
}
a.forEach(print)
// a
// b
Array.apply(null, a).forEach(print)
// a
// undefined
// b
利用数组对象的slice
方法,可以将一个类数组(比如arguments
对象)转为真正的数组。
Array.prototype.slice.apply({0: 1, length: 1}) // [1]
Array.prototype.slice.apply({0: 1}) // []
Array.prototype.slice.apply({0: 1, length: 2}) // [1, undefined]
//这个方法起作用的前提是,被处理的对象必须有length属性,以及相对应的数字键
bind()方法
bind()
方法用于将函数体内的this
绑定到某个对象,然后返回一个新函数。
var d = new Date();
d.getTime() // 1630997335855
var print = d.getTime
print() //this is not a Date object
上面代码报错了,是因为
getTime()
方法内部的this
,绑定Date
对象的实例,赋给变量this
已经不指向Date
对象的实例了。
//解决方案
var d = new Date();
var print = d.getTime.bind(d);
print() //1630997335855
上面代码中,bind()
方法将getTime()
方法内部的this
绑定到d
对象,这时就可以安全地将这个方法赋值给其他变量了。
var counter = {
count: 0,
inc: function () {
this.count++;
}
};
var func = counter.inc.bind(counter);
func();
counter.count // 1
上面代码中,counter.inc()
方法被赋值给变量func
。这时必须用bind()
方法将inc()
内部的this
,绑定到counter
,否则就会出错。
var add = function (x, y) {
return x * this.m + y * this.n;
}
var obj = {
m: 2,
n: 2
};
var newAdd = add.bind(obj, 5);
console.log(newAdd(4));//18
上面代码中,bind()
方法除了绑定this
对象,还将add()
函数的第一个参数x
绑定成5
,然后返回一个新函数newAdd()
,这个函数只要再接受一个参数y
就能运行了。
bind()
方法有一些使用注意点。
bind()
方法每运行一次,就返回一个新函数,这会产生一些问题。比如,监听事件的时候,不能写成下面这样。
element.addEventListener('click', o.m.bind(o));
click
事件绑定bind()
方法生成的一个匿名函数。这样会导致无法取消绑定
//应该这样写
var listener = o.m.bind(o);
element.addEventListener('click', listener);
// ...
element.removeEventListener('click', listener);
var obj = {
name: '潇洒',
times: [1, 2, 3],
print: function () {
this.times.forEach(function (n) {
console.log(this.name);
});
}
};
obj.print()
// 没有任何输出
--------------------------
//改写print方法
print :function () {
this.times.forEach(function (n) {
console.log(this.name);
}.bind(this));
}
obj.print()//潇洒 潇洒 潇洒
obj.print
内部this.times
的this
是指向obj
的,这个没有问题。但是,forEach()
方法的回调函数内部的this.name
却是指向全局对象,导致没有办法取到值。
JavaScript 闭包
var add = (function () {
var counter = 0;
return function () {return counter += 1;}
})();
add();
add();
add();
// 计数器目前是 3
变量 add 的赋值是自调用函数的返回值。
这个自调用函数只运行一次。它设置计数器为零(0),并返回函数表达式。
这样 add 成为了函数。最“精彩的”部分是它能够访问父作用域中的计数器。
这被称为 JavaScript 闭包。它使函数拥有“私有”变量成为可能。
计数器被这个匿名函数的作用域保护,并且只能使用 add 函数来修改。
闭包指的是有权访问父作用域的函数,即使在父函数关闭之后。
JSON方法
方法 | 描述 |
---|---|
parse() | 解析 JSON 字符串并返回 JavaScript 对象。 |
stringify() | 将 JavaScript 对象转换为 JSON 字符串。 |
JSON.parse()
方法用于将 JSON 字符串转换成对应的值。
JSON.parse()
方法可以接受一个处理函数,作为第二个参数,用法与JSON.stringify()
方法类似。
function f(key, value) {
if (key === 'a') {
return value + 10;
}
return value;
}
JSON.parse('{"a": 1, "b": 2}', f)
// {a: 11, b: 2}
上面代码中,JSON.parse()
的第二个参数是一个函数,如果键名是a
,该函数会将键值加上10。
如果对象的属性是undefined
、函数或 XML 对象,该属性会被JSON.stringify()
过滤。
var obj = {
a: undefined,
b: function () {}
};
JSON.stringify(obj) // "{}"
上面代码中,对象obj
的a
属性是undefined
,而b
属性是一个函数,结果都被JSON.stringify
过滤。
如果数组的成员是undefined
、函数或 XML 对象,则这些值被转成null
。
var arr = [undefined, function () {}];
JSON.stringify(arr) // "[null,null]"
上面代码中,数组arr
的成员是undefined
和函数,它们都被转成了null
。
正则对象会被转成空对象。
JSON.stringify(/xiaosa/) // "{}"
JSON.stringify()
方法会忽略对象的不可遍历的属性。
var obj = {};
Object.defineProperties(obj, {
'foo': {
value: 1,
enumerable: true
},
'bar': {
value: 2,
enumerable: false
}
});
JSON.stringify(obj); // "{"foo":1}"
定时器
如果回调函数是对象的方法,那么setTimeout
使得方法内部的this
关键字指向全局环境,而不是定义时所在的那个对象。
var x = 1;
var obj = {
x: 2,
y: function () {
console.log(this.x);
}
};
setTimeout(obj.y, 1000) // 1
上面代码输出的是1,而不是2。因为当obj.y
在1000毫秒后运行时,this
所指向的已经不是obj
了,而是全局环境。
一种解决方法是将obj.y
放入一个函数。
var x = 1;
var obj = {
x: 2,
y: function () {
console.log(this.x);
}
};
setTimeout(function () {
obj.y();
}, 1000);
// 2
上面代码中,obj.y
放在一个匿名函数之中,这使得obj.y
在obj
的作用域执行,而不是在全局作用域内执行,所以能够显示正确的值。
debounce防抖 短时间内多次触发同一事件,只执行最后一次,或者只执行最开始的一次,中间的不执行。
function debounce(fn, delay){
var timer = null; // 声明计时器
return function() {
var context = this;
var args = arguments;
if(timer) clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(context, args);
}, delay);
};
}
throttle节流 在 一定时间 之内,限制 一个动作 只 执行一次
function throttle(fn,wait){
var timer = null;
return function(){
var context = this;
var args = arguments;
if(!timer){
timer = setTimeout(function(){
fn.apply(context,args);
timer = null;
},wait)
}
}
}
等到当前脚本的同步任务,全部处理完以后,才会执行setTimeout指定的回调函数f
。也就是说,setTimeout(f,0))
会在下一轮事件循环一开始就执行。promise.then()比setTimeout(f,0)执行早,因为promise.then(f,0)是本轮事件循环执行,setTimeout(f,0)在下一轮事件循环开始时执行。
setTimeout(function () {
console.log(1);
}, 0);
console.log(2);
// 2
// 1
DOM
Node接口
Node 对象定义了几个常量,对应这些类型值。
document.nodeType === Node.DOCUMENT_NODE // true
文档节点(document):9,对应常量Node.DOCUMENT_NODE
元素节点(element):1,对应常量Node.ELEMENT_NODE
属性节点(attr):2,对应常量Node.ATTRIBUTE_NODE
文本节点(text):3,对应常量Node.TEXT_NODE
Node.prototype.nodeName 返回节点的名称。
// <div id="d1">hello world</div>
var div = document.getElementById('d1');
div.nodeName // "DIV"
Node.prototype.nodeValue 返回一个字符串,表示当前节点本身的文本值,该属性可读写。
// <div id="d1">hello world</div>
var div = document.getElementById('d1');
div.nodeValue // null
div.firstChild.nodeValue // "hello world"
上面代码中,div
是元素节点,nodeValue
属性返回null
。div.firstChild
是文本节点,所以可以返回文本值。
Node.prototype.textContent 返回当前节点和它的所有后代节点的文本内容
Node.prototype.baseURL 返回一个字符串,表示当前网页的绝对路径。浏览器根据这个属性,计算网页上的相对路径的 URL。该属性为只读
Node.prototype.nextSibling Node.prototype.previousSibling Node.prototype.parentNode 等等,详细可看Node 接口 - JavaScript 教程 - 网道
事件
EventTarget.addEventListener()用于在当前节点或对象上(即部署了 EventTarget 接口的对象),定义一个特定事件的监听函数。一旦这个事件发生,就会执行监听函数。该方法没有返回值。
target.addEventListener(type, listener[, useCapture]);
type
:事件名称,大小写敏感。listener
:监听函数。useCapture
:布尔值,如果设为true
,表示监听函数将在捕获阶段(capture)触发。默认值为false
(监听函数只在冒泡阶段被触发)。
一个事件发生后,会在子元素和父元素之间传播(propagation)。这种传播分成三个阶段。
第一阶段:从window
对象传导到目标节点(上层传到底层),称为“捕获阶段”(capture phase)。
第二阶段:在目标节点上触发,称为“目标阶段”(target phase)。
第三阶段:从目标节点传导回window
对象(从底层传回上层),称为“冒泡阶段”(bubbling phase)。
Event.preventDefault()方法取消浏览器对当前事件的默认行为。比如点击链接后,浏览器默认会跳转到另一个页面,使用这个方法以后,就不会跳转了
// <input type="checkbox" id="my-checkbox" />
var cb = document.getElementById('my-checkbox');
cb.addEventListener(
'click',
function (e){ e.preventDefault(); },
false
);
上面代码中,浏览器的默认行为是单击会选中单选框,取消这个行为,就导致无法选中单选框。