来源:JavaScript高级程序设计(马特·弗里斯比)(李松峰)
js的组成
js由ECMAscript,DOM,BOM组成
ECMAscript为语法协议,不同版本不同更新
dom为api接口,解析html页面为dom树与网页交互
bom为浏览器api接口,用于控制浏览器扩展交互
html中的js:
1、延迟执行脚本到解析完成后再执行:defer属性,
<!DOCTYPE html>
<html>
<head>
<title>Example HTML Page</title>
<script defer src="example1.js"></script>
<script defer src="example2.js"></script>
</head>
<body>
<!-- 这里是页面内容 -->
</body>
</html>
2、异步执行脚本不保证程序出现次序:async属性
<!DOCTYPE html>
<html>
<head>
<title>Example HTML Page</title>
<script async src="example1.js"></script>
<script async src="example2.js"></script>
</head>
<body>
<!-- 这里是页面内容 -->
</body>
</html>
*3、动态执行脚本保证程序出现优先级:async属性
gibberish.js文件
let script = document.createElement('script');
script.src = 'gibberish.js';
script.async = false;
document.head.appendChild(script);
根目录文件
<link rel="preload" href="gibberish.js">
4、文档模式:浏览器解析前的声明
*5、元素,不支持脚本js时可以使用,则元素中的任何内容都不会被渲染。
<!DOCTYPE html>
<html>
<head>
<title>Example HTML Page</title>
<script defer="defer" src="example1.js"></script>
<script defer="defer" src="example2.js"></script>
</head>
<body>
<noscript>
<p>This page requires a JavaScript-enabled browser.</p>
</noscript>
</body>
</html>
语言基础
语法
1、语法区分大小写
2、语句关键字及保留字
break do in typeof
*case else *instanceof var
catch export new void
class extends return while
const finally *super with
continue for switch yield
*debugger function this
default if *throw
*delete import try
3、var声明和let声明,const声明
var声明为局部函数声明,为顺序声明,为全局声明,为提升声明。
let声明为块声明,条件声明,开辟未定义空间声明,不允许多次声明;
const声明为不可修改声明,其他与let相似,写死常量可用。
4、数据类型
"undefined"表示值未定义;
"boolean"表示值为布尔值;
"string"表示值为字符串;
"number"表示值为数值;(由于内存的限制,ECMAScript 并不支持表示这个世界上的所有数值。ECMAScript 可以表示的最小
数值保存在 Number.MIN_VALUE 中,这个值在多数浏览器中是 5e324;可以表示的最大数值保存在
Number.MAX_VALUE 中,这个值在多数浏览器中是 1.797 693 134 862 315 7e+308。)
"object"表示值为对象(而不是函数)或 null;
"function"表示值为函数;
"symbol"表示值为符号
NaN和undefined和null区别。
NaN为数字转换错误显示
undefined为未定义,但是已经声明
null为空值但是开辟了空间
5、操作符
一元操作符:±*/,i++,++i,
①负数的二进制表示
(1) 确定绝对值的二进制表示(如,对于18,先确定 18 的二进制表示);
(2) 找到数值的一补数(或反码),换句话说,就是每个 0 都变成 1,每个 1 都变成 0;
(3) 给结果加 1。
②按位非~
③按位与&
④按位或 |
⑤按位异或 ^ (1+1=0,1+0=1,0+0=0)
⑥ 左移右移(<<) (>>)
⑦全等不全等
let result1 = ("55" == 55); // true,转换后相等
let result2 = ("55" === 55); // false,不相等,因为数据类型不同
⑧条件操作符
let max = (num1 > num2) ? num1 : num2;
//如果 num1 大于 num2(条件表达式为 true),则将 num1 赋给 max。否则,将 num2 赋给 max。
6、语句
with 语句的用途是反复使用对象,其语法是:
//使用 with 语句的主要场景是针对一个对象反复操作,这时候将代码作用域设置为该对象能提供便利,如下面的例子所示:
let qs = location.search.substring(1);
let hostName = location.hostname;
let url = location.href;
//上面代码中的每一行都用到了 location 对象。如果使用 with 语句,就可以少写一些代码:
with(location) {
let qs = search.substring(1);
let hostName = hostname;
let url = href;
}
7、函数
略
变量、作用域与内存
1、原始值与引用值
//原始值:
let name1 = "Nicholas";
console.log(name1);//Nicholas
Undefined、Null、Boolean、Number、String 和 Symbol。
//引用值
let person = new Object();
person.name = "Nicholas";
console.log(person.name); // "Nicholas"
//原始值调用报错
let name = "Nicholas";
name.age = 27;
console.log(name.age); // undefined
JavaScript 不允许直接访问内存位置,于是有了引用值。两者储存方式不同,复制值引用会产生变化原始不会变化,同样在函数中原始值不会继承,而引用值会继承,但在函数内只能操作不能继承,用typeof确定类型
2、作用域链
略
3、垃圾回收
①标记清理
在垃圾回收的运行中,会标记内存储存的所有变量,然后,他会把所有在上下文中的变量以及上下文引用的变量的标记去掉,在此之后加上标记的变量就是待删除的变量了,于是就进行一次内存清理
②引用计数
其思路是对每个值都记录它被
引用的次数。声明变量并给它赋一个引用值时,这个值的引用数为 1。如果同一个值又被赋给另一个变
量,那么引用数加 1。类似地,如果保存对该值引用的变量被其他值给覆盖了,那么引用数减 1。当一
个值的引用数为 0 时,就说明没办法再访问到这个值了,因此可以安全地收回其内存了。垃圾回收程序
下次运行的时候就会释放引用数为 0 的值的内存,但是存在致命缺点循环使用,为了补救于是将dom和bom对象都改成了javascript对象。
③内存管理建议
通过 const 和 let 声明提升性能以使得垃圾回收更早的介入; 隐藏类和删除操作,Chrome 中会使用 V8 JavaScript 引擎将创建的对象与隐藏类关联起来,以跟踪它们的属性特征,事实上就是this的用法;
内存泄漏:下面的代码没有使用任何关键字声明
变量:
function setName() {
name = 'Jake';
}
此时,解释器会把变量 name 当作 window 的属性来创建(相当于 window.name = ‘Jake’)。可想而知,在 window 对象上创建的属性,只要 window 本身不被清理就不会消失。这个问题很容易解决,但是定时器和闭包也一样容易导致内存泄漏
//定时器回调函数中引用的 name 就会一直占用内存。垃圾回收程序当然知道这一点,
let name = 'Jake';
setInterval(() => {
console.log(name);
}, 100);
//使用 JavaScript 闭包很容易在不知不觉间造成内存泄漏,只要返回就不能清理name
let outer = function() {
let name = 'Jake';
return function() {
return name;
};
};
静态分配与对象池:
为了减少垃圾回收的次数,我们会减少创建矢量对象,一种策略是创建对象池,但对象池本身就有空间限制,在数据过大的时候难以使用,所以静态分配一般在前期使用。
//静态分配
let vectorList = new Array(100);
let vector = new Vector();
vectorList.push(vector);
基本引用类型
引用
1、date类型:(表格)
了两个辅助方法:Date.parse()和 Date.UTC()。
略
2、regexp类型:正则表达式理解即可
3、原始值包装类型:
每当用到某个原始值的方法或属性时,后台都会创建一个相应原始包装类型的对象,从而暴露出操作原始值的各种方法。
4、单例内置对象
Global对象:Global 对象在大多数 ECMAScript 实现中无法直接访问。不过,浏览器将其实现为 window 对象。所有全局变量和函数都是 Global 对象的属性。
Math对象:Math 对象包含辅助完成复杂计算的属性和方法。
//string原始值包装类型
let s1 = "some text";
let s2 = s1.substring(2);
console.log(s2);//"me text"