JS高级程序设计

JS简介

HTML中使用JS

script元素

属性:

  • type:可选。代替 language,表示代码块中脚本语言的内容类型(也称 MIME 类型)。按照惯例,这个值始终都是"text/javascript"。在非 IE 的浏览器中有效的其他值还有
    “application/javascript"和"application/ecmascript”

  • charset:可选。使用 src 属性指定的代码字符集。这个属性很少使用,因为大多数浏览器不在乎它的值。

  • crossorigin:可选。配置相关请求的CORS(跨源资源共享)设置。默认不使用CORS。crossorigin= "anonymous"配置文件请求不必设置凭据标志。crossorigin="use-credentials"设置凭据标志,意味着出站请求会包含凭据。

  • integrity:可选。允许比对接收到的资源和指定的加密签名以验证子资源完整性(SRI,Subresource Integrity)。如果接收到的资源的签名与这个属性指定的签名不匹配,则页面会报错,脚本不会执行。这个属性可以用于确保内容分发网络(CDN,Content Delivery Network)不会提供恶意内容。

  • language:废弃。最初用于表示代码块中的脚本语言(如"JavaScript"、“JavaScript 1.2”
    或"VBScript")。大多数浏览器都会忽略这个属性,不应该再使用它。

  • 动态加载脚本src:可选。表示包含要执行的代码的外部文件。

let script = document.createElement('script'); 
script.src = 'gibberish.js';
//所有浏览器都支持 createElement()方法,但不是所有浏览器都支持 async 属性
script.async = false; //默认script异步加载,统一动态脚本的加载行为设为同步加载
document.head.appendChild(script);
  • 推迟执行脚本defer:可选。表示脚本可以延迟到文档完全被解析和显示之后再执行。只对外部脚本文件有效。在 IE7 及更早的版本中,对行内脚本也可以指定这个属性。标记为defer脚本应该按照它们出现的顺序执行

  • 异步执行脚本async:可选。表示应该立即开始下载脚本,但不能阻止其他页面动作,比如下载资源或等待其他脚本加载。只对外部脚本文件有效。标记为 async 的脚本并不保证能按照它们出现的次序执行

HTML引用外部JavaScript优点

  • 可维护性。
  • 缓存。浏览器会根据特定的设置缓存所有外部链接的 JavaScript 文件,这意味着如果两个页面都用到同一个文件,则该文件只需下载一次。这最终意味着页面加载更快。
  • 适应未来。通过把 JavaScript 放到外部文件中,就不必考虑用 XHTML 或前面提到的注释黑科技。包含外部 JavaScript 文件的语法在 HTML 和 XHTML 中是一样的。

语言基础

标识符(变量、函数、属性或函数参数的名称)

JavaScript区分大小写,通常使用驼峰表示,eg. myCar。
关键字、保留字、true、false 和 null 不能作为标识符。
关键字:
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
保留字:
enum
严格模式 - implements package public interface protected static let private
模块代码 - await

变量

var、let、const

varletconst
作用域函数的局部变量块作用域块作用域
变量提升
冗余声明❌声明同时必须初始化

注:
1.在函数内定义变量时省略 var 操作符,可以创建一个全局变量(window对象的属性)
全局变量缺点:
- 难维护
- 在严格模式下,如果像这样给未声明的变量赋值,则会导致抛出ReferenceError。

function test() { 
 var message = "hi"; // 局部变量
 quanju = "hello"
} 
test(); 
console.log(message); // 出错!
console.log(quanju); // "hello"

2.var、let和定时器

for (var i = 0; i < 5; ++i) { 
 setTimeout(() => console.log(i), 0) 
}
//5 5 5 5 5     在退出循环时,迭代变量保存的是导致循环退出的值5

for (let i = 0; i < 5; ++i) { 
 setTimeout(() => console.log(i), 0) 
}
//1 2 3 4 5     每个迭代循环声明一个新的迭代变量,也可用for-in 和 for-of

3. 暂存性死区”:在 let 声明之前的执行瞬间,抛出ReferenceError。
4.const 声明的限制只适用于它指向的变量的引用。换句话说,如果 const 变量引用的是一个对象,那么修改这个对象内部的属性并不违反 const 的限制。

更精确地声明作用域:不使用 var,const 优先,let 次之。

数据类型

原始类型:Undefined、Null、Boolean、Number、String 和 Symbol

typeof

 "undefined"表示值未定义;
 "boolean"表示值为布尔值;
 "string"表示值为字符串;
 "number"表示值为数值;
 "object"表示值为对象(而不是函数)或 null;  "function"表示值为函数;
 "symbol"表示值为符号。

undefined

当使用 var 或 let 声明了变量但没有初始化时,就相当于给变量赋予了 undefined 值。
对未声明的变量,只能执行一个有用的操作,就是对它调用 typeof。(对未声明的变量调用 delete 也不会报错,但这个操作没什么用,实际上在严格模式下会抛出错误。)

null

null 值表示一个空对象指针,typeof null 会返回"object"

Boolean 类型

数据类型转换为 true 的值转换为 false 的值
Booleantruefalse
String非空字符串“”(空字符串)
Number非零数值(包括无穷值)0、NaN(参见后面的相关内容)
Object任意对象null
UndefinedN/A(不存在)undefined

Number 类型

8进制:第一个数字必须是零(0),然后是相应的八进制数字(数值 0~7)。

let octalNum1 = 070; // 八进制的 56 
let octalNum2 = 079; // 无效的八进制值,有数字超过7,当成十进制 79 处理

注:严格模式无效,抛出错误

16进制:前缀 0x(区分大小写),然后是十六进制数字(0~9 以 及 A~F)。

let hexNum1 = 0xA; // 十六进制 10 
let hexNum2 = 0x1f; // 十六进制 31

浮点数

科学计数法:
let floatNum = 3.125e7; // 3.125✖️10^7等于 31250000

浮点值的精确度最高可达 17 位小数,但在算术计算中远不如整数精确。
❗️❗️❗️ 0.1+0.2 ≠ 0.3

最大最小值
Number.MIN_VALUE 中,多数浏览器中是 5e-324;
Number.MAX_VALUE 中,多数浏览器中是 1.797 693 134 862 315 7e+308
判断是否是有限值:isFinite(num) = boolean

NaN

console.log(isNaN("10")); // false,可以转换为数值 10 
console.log(isNaN("blue")); // true,不可以转换为数值
console.log(isNaN(true)); // false,可以转换为数值 1

isNaN():valueOf()➡️确定返回的值是否可以转换为数值➡️不能➡️调用 toString()方法➡️测试其返回值。

数值转换

Number() 、parseInt()、parseFloat()

Number()
parseInt()
字符串是否包含数值模式:从第一个非空字符开始,如果第一个字符不是数值字符、加号或减号,返回NaN。空字符返回NaN。
parseFloat() :只解析10进制
16进制 —> 0
10进制 —> 开头0被忽略

Number('')     ---> 0
parseInt('')   ---> NaN
parseFloat('') ---> NaN
进制转换
parseInt(10, 8)  --->8进制解析, 8
parseInt(10, 2)  --->2进制解析, 2
parseInt(10, 10) --->10进制解析 ,10
parseInt(10, 16) --->16进制解析 ,16
parseInt(3, 2)   --->2进制解析(3不是二进制),NaN
parseInt(3, 0)   ---> NaN / 报错

String 类型

字符字面量
特点

一旦创建,它们的值就不能变了。要修改某个变量中的字符串值,必须先销毁原始的字符串,然后将包含新值的另一个字符串保存到该变量

toString()转换为字符串/进制转换
let num = 10;
console.log(num.toString()); // "10" 
console.log(num.toString(2)); // "1010" 
console.log(num.toString(8)); // "12" 
console.log(num.toString(10)); // "10" 
console.log(num.toString(16)); // "a"

null 和 undefined 没有 toString()方法。

字符串插值
let str = `add ${ value }  }`;
String.raw’str’

直接获取原始的模板字面量内容(如换行符或 Unicode 字符)

console.log(`\u00A9`); // © 
console.log(String.raw`\u00A9`); // \u00A9

Symbol 类型

符号是原始值,且符号实例是唯一、不可变的。
Symbol()函数不能与 new 关键字一起作为构造函数使用

Object类型

Object 实例属性和方法:

  • constructor:用于创建当前对象的函数。
  • hasOwnProperty(propertyName):用于判断当前对象实例(不是原型)上是否存在给定的属性。属性名必须是字符。
  • isPrototypeOf(object):用于判断当前对象是否为另一个对象的原型。
  • propertyIsEnumerable(propertyName):用于判断给定的属性是否可以使用for-in 语句枚举。属性名必须是字符串。
  • toLocaleString():返回对象的字符串表示,该字符串反映对象所在的本地化执行环境。
  • toString():返回对象的字符串表示。
  • valueOf():返回对象对应的字符串、数值或布尔值表示。通常与 toString()的返回值相同。

操作符

一元操作符:只操作一个值的操作符,“+”、“-”、“++”、“–”。
对于字符串:对其进行一元操作符运算,字符串变数值(转不成是NaN)。
对于布尔值:对其进行一元操作符运算,字符串变0/1。
对于对象:则调用 valueOf()方法取得可以操作的值。如果是 NaN,则调用 toString()并再次应用其他规则。变量类型从对象变成数值。

位操作符

有符号整数使用 32 位表示(符号位+数值)。
负值以一种称为二补数(或补码)的二进制编码存储。

  1. 按位非"~"(速度快)= 数值取反并减 1
  2. 按位与“&”
  3. 按位或“|”
  4. 按位异或“^”
  5. 左移“<<”,数值 2(二进制 10)向左移 5 位,就会得到 64(二进制 1000000)
  6. 有符号右移“>>”,负数用补码右移

布尔操作符

  1. 逻辑非“!”,!!—>Bollean()
  2. 逻辑与“&&”,短路的特性,第一个false就不看第二个。
    如果第一个操作数是对象,则返回第二个操作数。
    如果第二个操作数是对象,则只有第一个操作数求值为 true 才会返回该对象。
    如果两个操作数都是对象,则返回第二个操作数。
    如果有一个操作数是 null,则返回 null。
    如果有一个操作数是 NaN,则返回 NaN。
    如果有一个操作数是 undefined,则返回 undefined。
  3. 逻辑或“||”,短路的特性,第一个true就不看第二个。
    如果第一个操作数是对象,则返回第一个操作数。
    如果第一个操作数求值为 false,则返回第二个操作数。
    如果两个操作数都是对象,则返回第一个操作数。
    如果两个操作数都是 null,则返回 null。
    如果两个操作数都是 NaN,则返回 NaN。
    如果两个操作数都是 undefined,则返回 undefined。

乘性操作符,指数操作符,加性操作符,关系操作符,相等操作符,条件操作符,赋值操作符,逗号操作符

乘性操作符:乘法“*”、除法“/”和取模“%”。
指数操作符

Math.pow(3, 2) ---> 9
let squared = 3;
squared **= 2;
console.log(squared); // 9,3的2次方

加性操作符:“+”、“-”
关系操作符:小于(<)、大于(>)、小于等于(<=)和大于等于(>=)
如果操作数都是数值,则执行数值比较。
如果操作数都是字符串,则逐个比较字符串中对应字符的编码。
如果有任一操作数是数值,则将另一个操作数转换为数值,执行数值比较。
如果有任一操作数是对象,则调用其 valueOf()方法,取得结果后再根据前面的规则执行比较。
如果没有 valueOf()操作符,则调用 toString()方法,取得结果后再根据前面的规则执行比较。
如果有任一操作数是布尔值,则将其转换为数值再执行比较。
相等操作符:“==”、“!=”、“===”、“!==”会先强制类型转换再比较。null == undefined
条件操作符:
let max = (num1 > num2) ? num1 : num2;
赋值操作符:
乘后赋值(*=)、除后赋值(/=)、 取模后赋值(%=)、加后赋值(+=)、 减后赋值(-=)、左移后赋值(<<=)、右移后赋值(>>=)、无符号右移后赋值(>>>=)
逗号操作符
let num1 = 1, num2 = 2, num3 = 3;

语句

do-while 语句

循环体中的代码执行后才会对退出条件进行求值

do { 
 statement 
} while (expression);
for-in 语句

由于对象的属性是无序的,因此不能保证返回对象属性的顺序

for (property in expression) statement
for-of 语句

循环会按照可迭代对象的 next()方法产生值的顺序迭代元素。

for (property of expression) statement
break 和 continue 语句

break 语句用于立即退出循环,强制执行循环后的下一条语句。
continue 语句也用于立即退出循环,但会再次从循环顶部开始执行。

标签语句
label: statement 

变量、作用域与内存

原始值与引用值

原始值(primitive value)就是最简单的数据,保存原始值的变量是按值(by value)访问的。
复制—>新建内存空间存储变量
引用值(reference value)则是由多个值构成的对象,保存引用值的变量是按引用(by reference)访问的,只有引用值可以动态添加后面可以使用的属性。
复制—>指针指向堆内存

难点

对象是按值传递的
function setName(obj) { 
obj.name = "Nicholas"; 
obj = new Object(); 
obj.name = "Greg"; 
} 
let person = new Object(); 
setName(person); 
console.log(person.name); // "Nicholas"
如果 person 是按引用传递的,那么 person 应该自动将指针改为指向 name 为"Greg"的对象。
可是,当我们再次访问 person.name 时,它的值是"Nicholas",
这表明函数中参数的值改变之后,原始的引用仍然没变。当 obj 在函数内部被重写时,它变成了一个指向本地对象的指针。而那个本地对象在函数执行结束时就被销毁了。

instanceof

用来判断对象是不是某个构造函数的实例,沿着原型链找。

result = variable instanceof constructor

执行上下文&作用域

上下文中的代码在执行的时候,会创建变量对象的一个作用域链(scope chain)。它决定了代码在访问变量和函数时的顺序。

内部上下文可以通过作用域链访问外部上下文中的一切,但外
部上下文无法访问内部上下文中的任何东西。上

  1. 使用 var 的函数作用域声明
function add(num1, num2) { 
 var sum = num1 + num2; 
 return sum; 
} 
let result = add(10, 20); // 30 
console.log(sum); // 报错:sum 在这里不是有效变量

//如果变量未经声明就被初始化了,那么它就会自动被添加到全局上下文
function add(num1, num2) { 
sum = num1 + num2; 
 return sum; 
} 
let result = add(10, 20); // 30 
console.log(sum); // 30
  1. 使用 let 的块级作用域声明

  2. 使用 const 的常量声明
    使用 const 声明的变量必须同时初始化为某个值。一经声明,在其生命周期的任何时候都不能再重新赋予新值。
    赋值为对象的 const 变量不能再被重新赋值为其他引用值,但对象的键则不受限制。
    如果想让整个对象都不能修改,可以使用 Object.freeze({})。再赋值不会报错,报undefined。

垃圾回收

定义:确定哪个变量不会再使用,然后释放它占用的内存。
特点:周期性

方法

标记清理

  1. 获取根,标记。
  2. 访问标记对象并标记他们的引用
  3. 以此类推,
  4. 除标记对象,剩下都删除

引用计数

  1. 记录引用次数
  2. 引用一次+1,引用被覆盖-1
  3. 引用=0,回收
    *循环引用会一直存在,占内存,该方法被放弃。

性能
如果数据不再必要,那么把它设置为 null,从而释放其引用。这也可以叫作解除引用。这个建议最适合全局变量和全局对象的属性。
局部变量在超出作用域后会被自动解除引用。

  1. 通过 const 和 let 声明提升性能
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值