这是对平时的一些读书笔记和理解进行整理的第二部分,第一部分请前往:你可能遗漏的JS知识点(一)。本文包含一些易混淆、遗漏的知识点,也会配上一些例子,也许不是很完整,也许还会有点杂,但也许会有你须要的,后续会持续更新,喜欢就关注一下喽!
html
1.易忽略的例子:git
let obj = { x: 1, y: 2};
"toString" in obj; //true obj继承了toString()方法且in能遍历原型上的不可枚举属性
let arr =[ 3, 6 ,8];
"0" in arr; //true 数组包含有0索引属性
复制代码
2.运算子的不一样,致使了不一样的语法行为,这种现象称为“重载”(overload)。加号会发生重载,由于加号可当成加法运算,也可做为字符串链接符,而减法,除法和乘法不会发送重载,由于都是做为数学运算使用。github
3.余数运算符(%)的运算结果的正负号由第一个运算子的正负号决定:正则表达式
-1 % 2 // -1
1 % -2 // 1
10 % 0 // NaN
10 % '0' // NaN
10 % 1 // 0
2 % 3 // 2
复制代码
with
:用于设置代码在特定对象中的做用域。express
eval
:可计算某个字符串,并执行其中的的 JavaScript 代码。数组
void
:做用是执行一个表达式,而后不返回任何值,或者说返回undefined。app
逗号运算符:用于对两个表达式求值,并返回后一个表达式的值。dom
'a', 'b' // "b"
var x = 0;
var y = (x++, 10);
x; // 1
y; // 10
复制代码
5.优先级:!> && > || > 三目运算符,等号优先级较低,逗号优先级更低。函数
//例一:
true || false && false
//至关于:
true || (false && false) // true
//例二:
var a = 42, b;
b = (a++, a); // 由于括号包了起来,优先级比=高,因此优先运算括号内的结果,先a++,而后再a,获得结果后再赋值给b
a; // 43
b; // 43
复制代码
6.三目运算符可适当代替if else。post
1.Date
对象是JavaScript原生的时间库。它以1970年1月1日00:00:00做为时间的零点,能够表示的时间范围是先后各1亿天(单位为毫秒),是构造函数。
2.直接调用Date老是返回当前时间,为字符串,且传入参数无效:
Date(); // "Wed Feb 19 2018 16:57:42 GMT+0800 (中国标准时间)"
Date(2000, 1, 1); // "Wed Feb 19 2018 16:57:42 GMT+0800 (中国标准时间)"
复制代码
3.new Date()
返回当前日期,为对象,也可接受多种格式的参数,返回一个该参数对应的时间实例:
new Date(); // Wed Dec 19 2018 17:03:59 GMT+0800 (中国标准时间)
复制代码
new Date(1378218728000); // Tue Sep 03 2013 22:32:08 GMT+0800 (中国标准时间)
复制代码
new Date(-1378218728000); // Fri Apr 30 1926 17:27:52 GMT+0800 (中国标准时间)
复制代码
new Date(2018, 0, 1, 0, 0, 0, 0); // Mon Jan 01 2018 00:00:00 GMT+0800 (中国标准时间)
复制代码
new Date('January 6, 2018'); // Sat Jan 06 2018 00:00:00 GMT+0800 (中国标准时间)
复制代码
new Date('2018-2-15')
new Date('2018/2/15')
new Date('02/15/2018')
new Date('2018-FEB-15')
new Date('FEB, 15, 2018')
new Date('FEB 15, 2018')
new Date('Feberuary, 15, 2018')
new Date('Feberuary 15, 2018')
new Date('15 Feb 2018')
new Date('15, Feberuary, 2018')
// Thu Feb 15 2018 00:00:00 GMT+0800 (中国标准时间)
复制代码
4.Date.now()
:
//Date.now方法返回当前时间距离时间零点(1970年1月1日 00:00:00 UTC)的毫秒数
Date.now() // 1545211158395
Date.now() === new Date().getTime() // true
复制代码
5.Date.parse()
:
Date.parse
方法用来解析日期字符串,返回该时间距离时间零点(1970年1月1日 00:00:00)的毫秒数:
Date.parse('Aug 9, 2018')
Date.parse('January 26, 2018 13:51:50')
Date.parse('Mon, 25 Dec 2018 13:30:00 GMT')
Date.parse('Mon, 25 Dec 2018 13:30:00 +0430')
Date.parse('2018-10-10')
Date.parse('2018-10-10T14:48:00')
复制代码
6.数据接口通常使用时间戳,由于时间戳在哪一个时区都是同样的。
7.能够将日期的内部表达形式当成一个整数类型的timestamp
, 而其余的表达形式只不过是这种内部形式的‘糖衣’,因此new Date()
实例的valueOf()
返回的是一个timestamp
就很容易理解了:
new Date().valueOf(); // 1542004695697
// 因此new Date()转换为整型只须要一个加号+,由于会自动调用valueOf()方法。
//以上等同于如下方式:
var d = new Date();
d.valueOf(); // 1542004695697
d.getTime(); // 1542004695697
Date.parse(d); // 1542004695697
Date.now(); // 1542004695697
复制代码
8.get
方法:
getTime()
:返回实例距离1970年1月1日00:00:00的毫秒数,等同于valueOf方法。getYear()
:返回距离1900的年数。getFullYear()
:返回四位的年份。getMonth()
:返回月份(0表示1月,11表示12月)。getDate()
:返回实例对象对应每月的几号(从1开始)。getDay()
:返回星期几,星期日为0,星期一为1,以此类推。getHours()
:返回小时(0-23)。getMinutes()
:返回分钟(0-59)。getSeconds()
:返回秒(0-59)。getMilliseconds()
:返回毫秒(0-999)。getTimezoneOffset()
:返回当前时间与 UTC 的时区差别,以分钟表示,返回结果考虑到了夏令时因素。9.set
方法:
setTime(milliseconds)
:设置毫秒时间戳。setYear(year)
: 设置距离1900年的年数。setFullYear(year [, month, date])
:设置四位年份。setMonth(month [, date])
:设置月份(0-11)。setDate(date)
:设置实例对象对应的每月的几号(1-31),返回改变后毫秒时间戳。setHours(hour [, min, sec, ms])
:设置小时(0-23)。setMinutes(min [, sec, ms])
:设置分钟(0-59)。setSeconds(sec [, ms])
:设置秒(0-59)。setMilliseconds()
:设置毫秒(0-999)。var d = new Date();
// 将年份设为去年:
d.setFullYear(d.getFullYear() - 1);
// 将日期向后推1000天:
d.setDate(d.getDate() + 1000);
// 将时间设为6小时后:
d.setHours(d.getHours() + 6);
复制代码
10.UTC时间比北京时间晚8小时。
1.Math
是 JavaScript 的原生对象,提供各类数学功能。该对象不是构造函数,不能生成实例,全部的属性和方法都必须在Math对象上调用。
2.Math.random()
获得的是包括0但不包括1的随机数。
Math.random() * 8 + 2; // 由于至少是大于或等于2,因此要加上2,同时又不能大于10,因此只能乘上8来保证小于8,而后加上2获得小于10的数
复制代码
function f() {
let a = Math.random() * 8 + 2, b;
b = 12 - a; // a确定是一个大于等于2但小于10的数,因此b为大于2但小于等于10的数
return b;
}
f(); // 8.199542416221309
复制代码
function getNumber() {
let a = Math.random(), b = 2, c;
while(a === 0){
a = Math.random();
}
c = a * 8 + b;
return c;
}
getNumber(); // 6.153494475244344
复制代码
Math.floor(Math.random() * 9 + 2); // 乘以个数再加上第一个数(第一个可能的值)
// 加2保证了至少等于2,而随机数乘9能获得不到于9的数,而后二者相加取整后能保证最大就是10
复制代码
3.Math.max()
Math.max.apply(null, [1,2,3]);
复制代码
Math.max(Math.min(1, 'input输入值若是不在1-2的范围内'), 12);
复制代码
1.全称:regular expression。
2.修饰符:g, i, m, u, y
3.元字符:
.
匹配除回车(\r)、换行(\n) 、行分隔符(\u2028)和段分隔符(\u2029)之外的全部字符。^
表示字符串的开始位置。 /^test/.test('test123'); // true
$
表示字符串的结束位置。 /test$/.test('new test'); // true
|
在正则表达式中表示"或关系"(OR)。 /11|22/.test('911') // true
4.量词符:用来设定某个模式出现的次数。
?
问号表示某个模式出现0次或1次,等同于{0, 1}*
星号表示某个模式出现0次或屡次,等同于{0,}+
加号表示某个模式出现1次或屡次,等同于{1,}// t 出现0次或1次
/t?est/.test('test') // true
/t?est/.test('est') // true
// t 出现0次或屡次
/t*est/.test('test') // true
/t*est/.test('ttest') // true
// t 出现1次或屡次
/t+est/.test('test') // true
/t+est/.test('ttest') // true
/t+est/.test('est') // false
复制代码
5.转义符: 须要反斜杠转义的一共有12个字符:^、.、[、$、(、)、|、*、+、?、{、\\
6.特殊字符:
[\b]
匹配退格键(U+0008),不要与\b混淆\n
匹配换行键\r
匹配回车键\t
匹配制表符 tab(U+0009)\v
匹配垂直制表符(U+000B)\f
匹配换页符(U+000C)\0
匹配null字符(U+0000)7.字符类: 要放到方括号内才有效,字符类(class)表示有一系列字符可供选择,只要匹配其中一个就能够了,好比[xyz] 表示x、y、z之中任选一个匹配。
/[abc]/.test('hello world') // false
/[abc]/.test('apple') // true
复制代码
①脱字符^
:必定是要放到方括号内,要和元字符^区分开,若是方括号内的第一个字符是[^],则表示除了字符类之中的字符,其余字符均可以匹配:
/[^abc]/.test('hello world') // true
/[^abc]/.test('bbc') // false
复制代码
②连字符-
:用来提供简写形式,表示字符的连续范围。
/a-z/.test('b') // false
/[a-z]/.test('b') // true
复制代码
8.重复类:使用大括号{}表示,{n}表示刚好重复n次,{n,}表示至少重复n次,{n,m}表示重复很多于n次,很少于m次。
/lo{2}k/.test('look') // true
/lo{2,5}k/.test('looook') // true
复制代码
9.预约义模式:指的是某些常见模式的简写方式。
\d
匹配0-9之间的任一数字,至关于[0-9]\D
匹配全部0-9之外的字符,至关于[^0-9]\w
匹配任意的字母、数字和下划线,至关于[A-Za-z0-9_]\W
除全部字母、数字和下划线之外的字符,至关于[^A-Za-z0-9_]\s
匹配空格(包括换行符、制表符、空格符等),相等于[ \t\r\n\v\f]\S
匹配非空格的字符,至关于[^ \t\r\n\v\f]\b
匹配词的边界\B
匹配非词边界,即在词的内部// 例:
/\s\w*/.exec('hello world'); // [" world"]
/\bworld/.test('hello world'); // true
/\bworld/.test('hello-world'); // true
/\bworld/.test('helloworld'); // false
/\Bworld/.test('hello-world'); // false
/\Bworld/.test('helloworld'); // true
var html = "<b>Hello</b>\n<i>world!</i>";
/[\S\s]*/.exec(html)[0]; // "<b>Hello</b>\n<i>world!</i>" [\S\s]指代一切字符
复制代码
①贪婪模式:默认状况下都是最大可能匹配,即匹配直到下一个字符不知足匹配规则为止。这被称为贪婪模式。
var s = 'aaa';
s.match(/a+/) ; // ["aaa"]
复制代码
②非贪婪模式:
*?
:表示某个模式出现0次或屡次,匹配时采用非贪婪模式。+?
:表示某个模式出现1次或屡次,匹配时采用非贪婪模式。var s = 'aaa';
s.match(/a+?/) ; // ["a"];
复制代码
11.组匹配:
/fred+/.test('fredd'); // true
/(fred)+/.test('fredfred'); // true
var m = 'abcabc'.match(/(.)b(.)/);
m; // ['abc', 'a', 'c']
// 能够用\n引用括号匹配的内容,n是从1开始的天然数,表示对应顺序的括号:
/(.)b(.)\1b\2/.test("abcabc"); // true
/y((..)\2)\1/.test('yabababab'); // true \1指向外层括号,\2指向内层括号
复制代码
12.正则的实例方法:test()和exec()都是正则放在前面。
test()
方法返回一个布尔值,表示当前模式是否能匹配参数字符串:/cat/.test('cats and dogs') // true
var r = /x/g;
var s = '_x_x';
r.lastIndex; // 0
r.test(s); // true
r.lastIndex; // 2
r.test(s); // true
r.lastIndex; // 4
r.test(s); // false
复制代码
exec()
方法,用来返回匹配结果。若是发现匹配,就返回一个数组,成员是匹配成功的子字符串,不然返回null:var s = '_x_x';
var r1 = /x/;
var r2 = /y/;
r1.exec(s); // ["x"]
r2.exec(s); // null
复制代码
13.字符串的实例方法:match()、search()、replace()、split(),正则放在后面。
match()
: 返回一个数组,成员是全部匹配的子字符串。var s = '_x_x';
var r1 = /x/;
var r2 = /y/;
s.match(r1); // ["x"]
s.match(r2); // null
// 设置正则表达式的lastIndex属性,对match方法无效,匹配老是从字符串的第一个字符开始:
var r = /a|b/g;
r.lastIndex = 7;
'xaxb'.match(r); // ['a', 'b']
r.lastIndex; // 0
复制代码
search()
:按照给定的正则表达式进行搜索,返回一个整数,表示匹配开始的位置。'_x_x'.search(/x/); // 1
复制代码
replace()
:按照给定的正则表达式进行替换,返回替换后的字符串。'aaa'.replace('a', 'b'); // "baa"
'aaa'.replace(/a/, 'b'); // "baa"
'aaa'.replace(/a/g, 'b'); // "bbb" 添加修饰符g才会进行总体替换,不然只替换第一个匹配
'JavaScript'.replace(/([A-Z])/g, '_$&') // "_Java_Script" ‘$&’表示所匹配到的文本,因此第一个就至关于匹配到J后,用_J来替换
let email = 'Betterman@163.com';
let username = email.replace(/(.*)@.*/, '$1'); // 'Betterman' 截取某段名称
// 回调函数返回所要替换的内容:
let re = /(.*)@(.*)\.(.*)/, glob;
let callback = function() {
glob = arguments;
return arguments[1] + ' at ' + arguments[2] + ' dot ' + arguments[3];
};
let res = 'Betterman@shenzhen.com'.replace(re, callback);
console.log(res); // Betterman at shenzhen dot com
console.log(glob); // ["Betterman@shenzhen.com", "Betterman", "shenzhen", "com", 0, "Betterman@shenzhen.com"]
// 正则表达式所匹配到的内容 第一组 第二组 第三组 匹配内容所在位置 所进行匹配的字符串(原字符串)
复制代码
split()
:按照给定规则进行字符串分割,返回一个数组,包含分割后的各个成员。// 非正则分隔:
'a, b,c, d'.split(','); // [ 'a', ' b', 'c', ' d' ] 注意有空格
// 正则分隔,去除多余的空格:
'a, b,c, d'.split(/, */); // [ 'a', 'b', 'c', 'd' ]
// 指定返回数组的最大成员数:
'a, b,c, d'.split(/, */, 2); // [ 'a', 'b' ]
// 或者:
let space = 'one, two,three ,four';
space.split(','); // ["one", " two", "three ", "four"] 有空格存在
space.split(/\s*,\s*/); // ["one", "two", "three", "four"] 无空格
复制代码
14.处理文章段落,给行首和行尾用正则raplace(/^/gn,'<p>').replace(/$/gn,'</p>')
来加上p标签。
1.面向对象:将真实世界各类复杂的关系,抽象为一个个对象,而后由对象之间的分工与合做,完成对真实世界的模拟。
2.面向对象具备封装性、继承性、多态性。把同类或者功能整理封装归类,须要什么就去找什么,就至关于把功能封装进对象,咱们只是把功能拿来用就行,而不须要了解其实现的原理,对象也不须要知道咱们用这个功能来作什么。
1.this永远指向最后调用它的那个对象(使用箭头函数除外)。
2.this判断:优先级
3.this绑定:
call
:参数应该是一个对象,若是参数为空、null和undefined,则默认传入全局对象,第一个参数就是this所要指向的那个对象,后面的参数则是函数调用时所需的参数:function add(a, b) {
return a + b;
}
add.call(this, 1, 2); // 3
复制代码
apply
:与call同样,只是参数为数组而已:// 找出数组最大元素
Math.max.apply(null, [10, 2, 4, 15, 9]); // 15
复制代码
bind
:返回一个新函数,而不是像call、apply直接执行返回值。1.可参考我以前写的一篇博客:完全弄懂JS原型与继承。
2.建立实例前与建立实例后修改构造函数原型的区别:
function Person () {}
let person1 = new Person();
Person.prototype = {
constructor: Person,
name: 'BetterMan',
age: 26,
sayName: function(){
console.log(this.name);
}
}
person1.sayName(); // 报错,实例依旧指向旧原型
复制代码
function Person () {}
Person.prototype = {
constructor: Person,
name: 'BetterMan',
age: 26,
sayName: function(){
console.log(this.name);
}
}
let person1 = new Person();
person1.sayName(); // "BetterMan"
复制代码
3.__proto__
实例.__proto__ === 构造函数.prototype // true
__proto__
虽然能够获得实例的原型,但__proto__
和prototype
不是等价的__proto__
其实是实例对象的属性,而prototype
是属于构造器函数的属性4.__proto__
与其说是属性,实际更像是getter/setter
,像一个函数,访问a.__proto__
时,其实是调用a.__proto__()
,__ptoto__
是继承自Object.prototype
:
Object.definedProperty(Object.prototype, '__proto__', {
get: function() {
return Object.getPrototypeOf(this);
},
set: function(o) {
return Object.setPrototypeOf(this, o);
}
})
复制代码
Object instanceof Object // true Object.__proto__===Function.prototype Function.prototype.__proto__===Object.prototype
Function instanceof Function // true Function.__proto__===Function.prototype
Function instanceof Object // true Function.__proto__===Function.prototype Function.prototype.__proto__===Object.prototype
复制代码
6.几种特殊的原型:
Object.getPrototypeOf({}) === Object.prototype // true
复制代码
Object.getPrototypeOf(Object.prototype) === null // true
复制代码
function f() {}
Object.getPrototypeOf(f) === Function.prototype // true
复制代码
7.Object.create()方法的基本原理:
function create(o) {
function F() {};
F.prototype = o;
return new F();
}
复制代码
1.类就像设计师设计出的蓝图,实例就像根据蓝图所建造出来的建筑。
2.js的类不像标准的类是复制一个副本,它相似于共享。
3.标准的继承应该是类与类之间的关系,而js的继承时“类”与实例之间的关系,或者应该说是对象与对象之间的关系。
4.继承的本来意思应该是复制,而js默认是不会复制对象属性的,相反,js会在两个对象之间建立一个关联,这样一个对象就能够经过委托
访问另外一个对象的属性和函数,进而找到所须要的属性,委托
行为意味着某些对象在找不到属性或方法时,会把这个请求委托给另外一个对象,这并非像父类到子类的关系垂直组织的,而是经过任意方向的委托关系并排组织的。
//ES6前:
B.prototype = new A();
//ES6:
Object.setPrototypeOf(B.prototype, A.prototype);
复制代码
//方式一:
F.prototype.isPrototypeOf(a);
//方式二:
Object.getPrototypeOf(a) === F.prototype;
复制代码
DOM2
事件流包含事件捕获、处于目标、事件冒泡三个阶段,addEventListener('事件名', '回调', '布尔值')
,第三个参数为true
时指在事件捕获阶段执行事件,为false
时为在冒泡阶段执行,默认为false
,IE只支持冒泡。
若是在同一个节点上同时设置了捕获事件和冒泡事件,若是该节点是目标节点,无论第三参数为什么,都会按照事件的书写顺序来执行(若是不是目标节点,则会按照先捕获后冒泡执行):
<div class="a1">
<div class="a2">
<div class="a3">a3</div>
</div>
</div>
var a1 = document.getElementsByClassName('a1')
var a2 = document.getElementsByClassName('a2')
var a3 = document.getElementsByClassName('a3')
a1[0].addEventListener('click', function (event) {
console.log('a1')
}, false)
a2[0].addEventListener('click', function (event) {
console.log('a2')
}, false)
a2[0].addEventListener('click', function (event) {
console.log('a22')
}, true)
a3[0].addEventListener('click', function (event) {
console.log('a33')
}, false) // 虽然为false, 但写在前会先执行
a3[0].addEventListener('click', function (event) {
console.log('a3')
}, true)
// 点击a3时:a22 a33 a3 a2 a1
复制代码
由于比较多,因此目前只整理到这里,后续有些比较重要难懂的模块会分开更新,同时包括ES6的部分,但愿对你有所帮助,若有不合理的地方欢迎指正,喜欢的话欢迎关注一波,后续会持续更新。