1

一、写在前面

最近重读《JavaScript高级程序设计》,总结下来,查漏补缺。

二、JS简介

2.1 JS组成

  • ECMAscript:以ECMA-262为基础的语言,由浏览器支持
  • DOM:编程接口(API), 将页面映射成节点结构(文档树),提供操作方法
  • BOM:浏览器对象模型,处理浏览器窗口和框架交互(部分扩展)

2.2 <script>

  • 实现在HTML中插入JS
  • 内嵌,外联(好处:可维护,可缓存,适应未来)
  • 推荐放在body中、内容后,缩短内容呈现时间(浏览器遇到body呈现内容)

参数:

  1. async: 立即下载脚本(外部文件),异步执行

    • 不保证按出现顺序执行
    • 多个async时,保证互不依赖,建议无修改DOM操作
    • 在页面load前执行,不一定在DOMContentLoaded事件触发前执行
  2. charset: 指定代码字符集(很少用,部分浏览器忽略该参数)
  3. defer: 下载后延迟执行,文档完全解析显示后执行

    • 延迟脚本,延迟到</html>后执行,页面load前执行
    • 最好只有一个延迟脚本(HTML5要求按出现顺序执行,但实际不一定按顺序执行,也不一定会在DOMContentLoaded事件触发前执行)
  4. language: 标明编写语言(废弃)
  5. src: 外部文件及地址链接

    • src、标签间嵌入内容同时存在,src下载执行,嵌入内容不被解析
  6. type: 标明内容类型(MIME类型),默认text/javascript

    • 其他application/x-javascript,application/javascript,application/ecmascript

2.3 文档模式

  • 混杂模式
  • 标准模式

2.4 <noscript>

早期浏览器不支持脚本/脚本被禁用时显示,使用noscript平稳退化

<body>
    <noscript>您的浏览器不支持脚本/脚本被禁用</noscript>
</body>

2.5 PS:

1. async和defer区别?

图片描述

蓝色线代表网络读取,红色线代表执行时间,均针对脚本;绿色线代表 HTML 解析。

  • 默认,同步,顺序解析,解析到立即加载,加载完立即执行。
  • defer,异步,同时加载,html解析完成后执行(多个,不一定按顺序执行,适用外链脚本)(HTML5要求按出现顺序执行,但实际不一定,不一定会在DOMContentLoaded事件触发前执行)
  • async,异步,同时加载,加载完立即执行(多个,乱序执行)

2. XHTML和HTML主要不同?

  • 元素必正确嵌套,防止<a><b></a></b>
  • 单标签< />、双标签<> </>闭合
  • 标签名、属性大小写敏感
  • 必须有根元素

三、基本概念

3.1 ECMAScript语法

区分大小写

  1. 标识符:

    • 参数,变量,属性,函数名
    • 以字母、下划线_、$开头
    • 惯例为驼峰
    • 名称不能为关键字
  2. 注释:

    • 单行注释 / /
    • 块级注释 /* */
  3. 严格模式: 编译指示" user strict "
  4. 语句:

    • 推荐以分号;结尾
    • if( ) 可省略代码块{ }直接书写语句,但推荐不省略
  5. 关键字:

    • break case catch continue debugger default delete
    • do else finally for function if in
    • instanceof new return switch this throw try
    • typeof var void while with
  6. 保留字:

    • abstract boolean byte char class const debugger double
    • enum export extends final float goto implements import
    • int interface long native package private protected public
    • short static super synchronized throws transient volatile
    • 外加let、yield、eval、arguments

3.2数据类型

变量:松散类型(可修改值的类型),var创建时有作用域

  • 只定义未初始化,值为undefined
  • 不推荐在局部中定义全局变量

数据类型:

  • 简单(基本)数据类型:number,string,Boolean,undef,null
  • 复杂数据类型:Object

typeof操作符:

  • 值:number,string,boolean,undefined,null,object,function
  • 特殊情况: typeof null ---> object 被认为是空对象指针

对象:

  • 空对象,初始化时obj = null 通过 obj != null 来看是否保存对象引用
  • 新建对象:new Object( ) 或 new Object

布尔:

  • true false 区分大小写

数值:

  • 八进制(严格模式下失效),0开头,后续值超过7则 079无效,解析为79
  • 十六进制,不区分大小写,0x开头欧,后续0-9、A-F
  • 科学计数法,123e7或123e-7,浮点数最大精度17位小数
  • 浮点数进行计算,结果不准确
  • 数值范围Number.MIN_VALUE 5e-324 ~ Number.MAX_VALUE 1.7976931348623157e+308,超出对应±infinity
  • NaN,返回不为数值,也为数值类型,不影响代码执行,操作NaN都返回NaN,与任何值都不相等

字符串:

  • 0或多个16位unicode字符组成
  • 单双引号无区别
  • 字符字面量:\n \t \b \r \f \\ \' \" \x \u 及6位unicode字符
  • 一旦创建,值不可改变,只能---->新的创建,销毁原来的(旧版浏览器执行速度慢)

3.3 方法

数值

  • isNaN( )隐式转换数值
  • Number( ),null ----> 0,undefined ---> NaN,八进制前导0失效,十六进制转换为十进制整数
  • parseInt( ),直到不是数字,保留整数,识别八进制、十六进制,可指定第二个参数parseInt(a,8)指定八进制
  • parseFloat( ),不解析前导0,可用于:科学计数法转完全展示

字符串:

  • toString(a) 参数可设置进制,数据转换值,有些不能转换(undefined,null)
  • String()遵循先按toString执行,不成功再按String()转换(undefined----> undefined , null ----> null )

对象:

  • constructor 创建实例的函数(构造函数)
  • hansOwnProperty 检查当前对象中存在某属性(不查原型)
  • isPrototypeOf 检查是否是某对象的原型
  • propertyIsEnumerable 能否使用for-in枚举
  • toLocaleString 返回对象字符串表示
  • toString( ) 对象的字符串表示
  • valueOf( ) 返回对象的字符串、数值或布尔值

3.3 操作符

算数、位、关系、相等操作符

一元操作符(隐式转换):

  • 只能操作一个值
  • 前置(副效应:语句被求值前值改变)
  • 后置(语句被求值后值改变)
  • 含对象,执行valueOf( ) 后得到的值进行加减

位操作符:

  • 转换为32位整数,31位二进制数+ 1位符号位(0正1负)
  • 按位非 ~ 得到值的负值 - 1(底层操作,比 - a - 1 快)
  • 按位与 & 二进制每位相与得出二进制值
  • 按位或 | 二进制每位相或得出二进制值
  • 按位异或^ 两位相异则为1,否则为0
  • 左移 << 移动后补0,不影响符号位
  • 右移 >> 保留符号位,移动后补0
  • 无符号右移 >>> 不保留符号位,负数一般右移后很大

布尔操作符:

  • 非 !
  • 与 && 短路操作(有 false 则不往下执行),null 返回null,NaN返回NaN ,undefined返回undefined
  • 或 || 短路操作(有true 则不往下执行 )

乘性操作符:

  • 隐式转换为数值后计算,/ 除法 ,% 取余

加性操作符:

  • + 加法, - 减法

关系操作符:

  • < 、 >、 <=、 >=
  • 都为字符串时,比较字符串字符编码值
  • 有对象,转valueOf( ),不成则toString( )
  • 字符串比较,大写小于小写,如需比较可全转小写
  • 都为字符串的数字,则按编码比
  • 一个数字一个字符串,会转为数值
  • 转换出NaN,则结果false

相等操作符:

  • 强制转换规则:有布尔转为数值、有数有字符串转为数值
  • 只有一个对象,按照valueOf()转换后比较
  • null == undefined,null !== undefined
  • 两个对象,比较是否指向同一对象

条件操作符:条件?‘真,取值’:‘假,取值’
赋值操作符:

  • =、 +=、 *=、 /=、 %=、 <<=、 >>=、 >>>=(简化书写,不影响性能)

逗号操作符:

  • 分隔多个操作
  • a =(1,2,3,4),a值为最后一个4

3.4 PS:

1. valueOf与toString

2. 负数的二进制表示:

  • 绝对值的二进制码,按位取反,加1,得到

3. 按位非运算符 ~

function fast() {
    let s = 2222222222; 
    let start1 = Date.now();
    for (var i = 1; i<10000000000;i++) { s = ~ s }; 
    console.log('fast',Date.now() - start1); 
 }; 
 function slow() {
    let s = 2222222222; 
    let start2 = Date.now();
    for (var i = 1; i<10000000000;i++) { s = - (s + 1) }; 
    console.log('slow',Date.now() - start2); 
 };
 fast();
 slow();

相差4-5秒左右,底层运算更快

4. && || 操作
let d = { name: 'aa' } ,??代表某参数

  • d && ?? 返回??
  • ?? && d ??为true返回d,否则返回??
  • 有null NaN undefined 返回 对应null NaN undefined
  • d || ?? 返回 d
  • ?? || d ??为false返回d
  • d || e 返回 d
  • 都是null NaN undefined 返回 对应null NaN undefined

3.5 语句

  • if (条件) { 代码块 }
  • do-while 后测试循环语句,while中满足则执行
  • while 前测试循环语句
  • for :while做不到,for也做不到、for( ; ; )三参数可选
  • for-in 循环对象属性,顺序不可预测
  • label 名字:语句,结合for循环,方便continue 名字 执行该操作,break 名字 中断名字操作
  • break continue
  • with 将代码作用域设置到特定对象中,影响性能,不建议使用
with(location) { 
    var t = search.name;
    var w = hostname;
}
// 等同于
var t = location.seatch.name;
var w = location.hostname;
  • switch 全等比较(不进行类型转换),可以合并情况,case可为变量、表达式,
switch (i) {
    case 25: 
        /* 合并两种情形 */
    case 35: 
        alert("25 or 35");
        break;
    ...
}

3.6 函数

function (参数) {函数体}

  • 定义的参数个数可以≠传入参数个数,适用传参个数不定执行不同操作
  • 可function acc(a)传acc( ) 或function acc()传acc(1,2)
  • 内部可用arguments来访问参数,如果a对应arguments[0],两值内存空间独立,但互相同步
  • 没有重载:函数没有签名,同名函数后定义的生效
读取这两个值会访问相同的内存空间;它们的内存空间是独立的,但它们的值会同步。但这种影响是单向的:修改命名参数不会改变arguments中对应的值。另外还要记住,如果只传入了一个参数,那么为arguments[1]设置的值不会反应到命名参数中。这是因为arguments对象的长度是由传入的参数个数决定的,不是由定义函数时的命名参数的个数决定的。

书中:修改命名参数不会改变arguments中对应的值。 实际改变arguments[0]会同步a ,改变a也会同步argumenets[0]


薄荷
15 声望0 粉丝

必有回响