JavaScript 高级程序设计笔记

记录下遗忘的知识点


part2: 在HTML中使用JavaScript

1.所有<script>元素都会按照他们在页面中出现的先后顺序依次被解析(不使用defer和async属性的情况下)。

  1. 只有 Internet Explorer 支持 defer 属性。

2.1. <script src="script.js"></script>

没有 defer 或 async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该 script 标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行。

2.2. <script async src="script.js"></script>

有 async,加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行进行(异步)。

2.3. <script defer src="myscript.js"></script>

有 defer,加载后续文档元素的过程将和 script.js 的加载并行进行(异步),但是 script.js 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成。

[图片上传失败...(image-407000-1560162831547)]

image.png

3.<noscript>:让页面平稳退化。

浏览器不支持脚本;

浏览器支持脚本,但脚本被禁用

Part3 基本概念

    1. ECMAScript5引入严格模式(严格模式下,ECMAScript3中的一些不确定的行为将得到处理,而且对某些不安全的操作也会抛出异常)
      使用方法:这个脚本顶部添加 'use strict'
  • 2.五种简单数据类型(基本数据类型)
    Undefined、Null、Bollean、Number、String
    一个复杂数据类型:Object

  • 3.undefined(声明了变量但未加以初始化)

  • 4.null (表示一个空指针)

  • 5.boolean 任何数据类型的值调用Boolean()函数,总会返回一个Boolean值,参照下图:

Boolean
  • 6.NaN(非数值是一个特殊的数值)表示一个本来要返回数值的操作数未返回数值的情况。
    特殊点:任何涉及NaN的操作都会返回NaN;NaN与任何数值都不想等,包括他本身。
    isNaN() :尝试转换为数值,不能被转换为数值的值返回 true。(转换数值知识点

  • 7.ECMAScript 中的所有参数传递的都是值,不可能通过引用传递参数。

  • 8.ECMAScript函数不能重载。


Part4 变量作用域和内存问题

  • 1.基本数据类型是按值访问的,因此可以操作保存在变量中的实际的值。
    引用类型的值时按引用访问的(JavaScript不允许直接访问内存中的 位置)

  • 2.检测基本数据类型时用 typeof 操作符
    检测引用类型的值时用 instanceof 操作符

  • 3.没有块级作用域

Paste_Image.png
Paste_Image.png

查询标识符,从作用域链的前端开始,向上逐级查询与给定名字匹配的标识符。

  • 4.垃圾收集:
    标记清除:算法的思想是给当前不使用的值加上标记,然后在回收其内存。
    第一阶段,标记所有的可访问对象.第一阶段叫做标记阶段.
    第二阶段,垃圾收集算法扫描堆并回收所有的未标记对象.第二阶段叫做收集阶段.
    引用计数:算法是思想是跟踪记录所有的值被引用的次数。
    引用计数对循环引用的垃圾回收会出现内存泄漏,而IE的DOM回收机制便是采用引用计数的。IE9+把BOM和DOM对象都转换成真正意义的JavaScript对象。避免两种垃圾收集算法的并存。

  • 5.解除变量的引用不仅有助于消除循环引用现象,而且对垃圾收集也有好处。为了确保有效地回收内存,应该及时解除不在使用的全局对象、全局对象属性以及循环引用变量的引用。


Part5 引用类型

对象是某个特定引用类型的实例

1.Object类型

创建方式:
① new操作符后跟Object构造函数
②使用对象字面量表示法。

2.Array类型

ECMAScript数组的每一项可以保存任何类型的数据。
创建方式:
①使用Array构造函数 eg: var arr= new Array();
②使用数组字面量表示法 eg: var arr=[1,2,'A'];
数组最多包含4294967295个项

2.1检测数组
ECMAScript新增 Array.isArray()

2.2转换方法
toString()
valueOf()
toLocaleString()
调用数组的 toString()方法会返回有数组中每个值的字符串形式拼接而成的一个以逗号分隔的字符串。
调用数组的 valueOf()方法会返回的还是数组。
toLocaleString()不同之处在于,为取到每一项的值,调用的是toLocaleString()方法,而不是toString()方法

join()方法可以使用不同的分隔符来构建这个字符串。 如, || *

2.3栈方法(后进先出)
push() 可以接收任意数量的参数,把他们逐个添加到数组末尾。并返回修改后数组的长度。
pop() 从数组末尾移除最后一项,减少数组的length值,返回移除的项。

2.4队列方法(先进先出)
shift() 移除数组中的第一个项并返回该项,同时将数组长度减一。
unshift()在数组前端添加任意个项并返回新数组的长度。

2.5重排序方法
reverse() 翻转数组项的顺序

sort() 方法时按升序排列数组项(调动数组项的toString()转型方法,比较字符串。)
arrayObject.sort(sortby)
sortby 可选。规定排序顺序。必须是函数。
给数值型数组排序时,可以定义排序函数

var arr = [12,5,8,40];
function sortNumber(a,b){
   return a - b  //  return b-a 为降序排列
}
arr.sort(sortNumber);

或者 复杂点

    var arr = [12,5,8,40];
    function compare(value1, value2) {
        if (value1 < value2) {
            return -1;
        } else if (value1 > value2) {
            return 1;
        } else {
            return 0;
        }
    }
    arr.sort(compare);

2.6操作方法
concat()
创建当前数组的一个副本,将接收到的参数添加到这个副本的末尾,最后返回新构建的数组,

slice()
arrayObject.slice(start,end)
start 必需。规定从何处开始选取。如果是负数,那么它规定从数组尾部开始算起的位置。也就是说,-1 指最后一个元素,-2 指倒数第二个元素,以此类推。
end 可选。规定从何处结束选取。该参数是数组片断结束处的数组下标。如果没有指定该参数,那么切分的数组包含从 start 到数组结束的所有元素。如果这个参数是负数,那么它规定的是从数组尾部开始算起的元素。

splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目。
arrayObject.splice(index,howmany,item1,.....,itemX)
index 必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。
howmany 必需。要删除的项目数量。如果设置为 0,则不会删除项目。
item1, ..., itemX 可选。向数组添加的新项目。

2.7位置方法
indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。
lastIndexOf() 方法可返回一个指定的字符串值最后出现的位置,在一个字符串中的指定位置从后向前搜索。

2.8迭代方法
map()是对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。这个数组的每一项都是在原始数据中的对应项上运行传入函数的结果
filter()是对数组中的每一项运行给定函数,返回该函数会返回true的项所组成的数组。它利用指定的函数确定是否在返回的数组中包含某一项
every()是对数组中的每一项运行给定函数,如果该函数对每一项都返回true,则返回true。
some()是对数组中的每一项运行给定函数,如果该函数对任一项返回true,则返回true。
forEach() 是多数组中的每一项运行给定函数,这个方法没有返回值。它只是对数组中的每一项运行传入的函数,没有返回值。本质上与使用for循环迭代数组一样。

2.9缩小方法
reduce() reduceRight()
迭代数组的所有项,然后构建一个最终返回的值。

3.Date类型
4.RegExp类型
5.Function类型

函数是对象,函数名是指针。

5.1 没有重载(两个同名函数,后面的会覆盖前面的函数)

5.2 函数声明与函数表达式
解析器会率先读取函数声明,并使其在执行任何代码前可用,
函数表达式,会在解析器执行到它所在是代码行,才会真正被解释执行。

5.3作为值的函数

5.4函数内部属性
特殊对象:arguments 和 this
用例:阶乘

  function factorial(num) {
        if (num <= 1) {
            return 1;
        } else {
            return num * arguments.callee(num - 1);
        }
    }

5.5函数属性和方法
每个函数都包含两个属性 length 和 prototype
length 表示函数希望接受的命名参数的个数。
prototype是保存他们所有实例方法的真实所在。

6基本包装类型

引用类型与基本包装类型的主要区别就是对象的生存期。

基本包装类型,也是一种引用类型。基本包装类型是对基本数据类型的封装,封装后即具有基本类型的功能,也有各自的特殊行为(方法)

基本包装类型需要一个new来创建。请看下面的例子:
1.字面量写法:var box = 'Mr. Lee';//字面量
box.name = 'Lee';//无效属性
box.age = function () {//无效方法
return 100;
};
alert(box);//Mr. Lee
alert(box.substring(2));//. Lee
alert(typeof box);//string
alert(box.name);//undefined
alert(box.age());//错误

2.new 运算符写法:var box = new String('Mr. Lee');//new 运算符
box.name = 'Lee';//有效属性
box.age = function () {//有效方法
return 100;
};
alert(box);//Mr. Lee
alert(box.substring(2));//. Lee
alert(typeof box);//object
alert(box.name);//Lee
alert(box.age());//100

6.1Boolean类型
6.2Number类型
6.3String类型

7.单体内置对象

Global对象
Math对象


Part6 面向对象的程序设计

ECMAScript中有两种属性:数据属性和访问器属性。

1.数据属性:
数据属性包含一个数据值的位置。在这个位置可以读取和写入值。数据属性有4个描述其行为的特性。
[[Configureable]]:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。默认值是true。
[[Enumerable]]:表示能否通过for-in 循环返回属性。默认值是true。
[[Writable]]:表示能否修改属性的值。默认值是true。
[[Value]]:包含这个属性的数据值。读取属性值的时候,从这个位置读;写入属性值的时候,把新值保存在这个位置。这个特性的默认值为undefined。
2.访问器属性
访问器属性不包含数据值;它们包含一对儿getter和setter函数。
[[Configurable]]:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为数据属性。默认值是true。
[[Enumerable]]:表示能否通过for-in 循环返回属性。默认值是true。
[[Get]]:在读取属性时调用的函数。默认值为undefined。
[[Set]]:在写入属性时调用的函数。默认值为undefined。

Object.defineProperty()
Object.defineProperties()
读取属性的特性:Object.getOwnPropertyDescriptor()

6.2创建对象

6.2.1工厂模式
    function createPerson(name, age, job) {
        let o = new Object()
        o.name = name
        o.age = age
        o.job = job
        o.sayName = function () {
            console.log(this.name)
        }
        return o
    }

    let person = createPerson('AA', 29, 'engineer')
    let person2 = createPerson('BB', 28, 'doctor')
6.2.2构造函数模式
    function Person(name, age, job) {
        this.name = name
        this.age = age
        this.job = job
        this.sayName = function () {
            console.log(this.name)
        }
    }

    let person = new Person('AA', 29, 'engineer')
    let person2 = new Person('BB', 28, 'doctor')
    console.log(person)
    console.log(person2)

与工厂模式不同之处:

  • 没有显式地创建对象
  • 直接将属性和方法赋给了this对象
  • 没有return语句
    缺点:
    每个方法都要在每个实例上重新创建一遍。
6.2.3原型模式
    function Person() {
    }

    Person.prototype.name= 'AA'
    Person.prototype.age= 29
    Person.prototype.job= 'engineer'
    Person.prototype.sayName = function(){
        console.log(this.name)
    }
    console.log(Object.getOwnPropertyNames(Person.prototype)) // ["constructor", "name", "age", "job", "sayName"]
    let person = new Person()
    let person2 = new Person()
    console.log(person.hasOwnProperty('name')) // false
    console.log('name' in person) // true
    person.name= 'CC'
    console.log(person.hasOwnProperty('name')) // true
    console.log('name' in person) // true
    delete person.name
    console.log(person.hasOwnProperty('name')) // false
    console.log('name' in person) // true

使用hasOwnProperty() 可以检查访问的是实例属性还是原型属性。
使用 in 操作符只要通过对象能访问到属性就返回true

  • 原型模式缺点:
    原型中所有属性是被很多实例共享的,这种共享对于函数非常合适,但是对于包含引用类型值的属性来说,就存在问题了。
6.2.4 组合使用构造函数模式与原型模式
    function Person(name,age,job) {
        this.name = name
        this.age = age
        this.job = job
        this.friends =['A','B']
    }


    Person.prototype = {
        constructor:Person,
        sayName :function(){
            console.log(this.name)
        }
    }

    let person = new Person('AA',29,'engineer')
    let person2 = new Person('BB',28,'doctor')

    person.friends.push('C')
    console.log(person.friends)
    console.log(person2.friends)
    console.log(person.sayName === person2.sayName)
6.2.5 动态原型模式
6.2.6寄生构造函数模式
6.2.7稳妥构造函数模式

6.3 继承

接口继承:只继承方法签名
实现继承:继承实际的方法
由于函数没有签名,在ECMAScript中无法实现接口继承,只支持实现继承,而且其实现继承主要是依靠原型链来实现的。

6.3.1 原型链

问题:
1.来自包含引用类型值的原型
2.没有办法在不影响所有对象实例的情况下,给超类型的构造函数传递参数。

6.3.2 借用构造函数
6.3.3 组合继承
6.3.4 原型式继承
6.3.5 寄生式继承
6.3.6 寄生组合式继承

Part7 函数表达式

  • 1.递归:是在一个函数通过名字调用自身的情况下构成的
  • 2.闭包:是指有权访问另一个函数作用域中的变量的函数

Part8 BOM

  • 1.BOM的核心对象是window,他表示浏览器的一个实例。

  • 2.全局变量 不能通过delete操作符删除,而直接在window对象上的定义的属性可以。

    1. JavaScript是单线程语言,但他允许通过设置超时值和间歇时间值来调度代码在特定的时刻执行。
      超时调用: setTimeout();
      间歇调用: setInterval();
  • 4.系统对话框
    alert()
    confirm()
    prompt()


Part9 客户端检测

  • 1.客户端检测是JavaScript开发中最具争议的一个话题。经常使用:
    能力检测:在编写代码之前先检测特定浏览器的能力。
    怪癖检测:实际上是浏览器实现中存在的bug。(无法精确检测特定的浏览器和版本)
    用户代理检测:通过检测用户代理字符串来识别浏览器。(万不得已才使用)

Part10 DOM

  • 最基本的节点类型时Node,用于抽象地表示文档中一个独立的部分,所有其他类型都继承自Node
    *jQuery 的核心就是通过CSS选择符查询DOM文档取得元素的引用。从而抛开了getElementById()和getElementByTagName()

Part13

  • 1.事件流描述的是从页面中接收事件的顺序。
  • 2.IE的事件流叫做事件冒泡。(所有现代浏览器都支持事件冒泡)
  • 3.事件捕获。相反,document对象首先接收到click事件,然后事件沿着DOM书依次向下。直到事件的实际目标。
  • 4.DOM事件流。包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。
  • 5.事件处理程序:
    HTML事件处理程序
    DOM0级事件处理程序
    DOM2级事件处理程序
    IE级事件处理程序
    跨浏览器的事件处理程序
  • 6.建立在事件冒泡机制智商的事件委托技术,可以有效的减少事件处理程序的数量。
  • 7.建议在浏览器卸载页面之前移除页面中的所有事件处理程序。

Part23 客户端存储

  • cookie 的限制使其可以存储少量的数据。
  • Web Storage定义了两种存储数据的对象,sessionStorage 和localStorage
    前者严格用于在一个浏览器会话中存储数据,因为数据在浏览器关闭后会立即删除。
    后者用于跨会话持久化数据并遵循跨域安全策略。
  • IndexedDB是一种类似SQL数据库的结构化数据存储机制。但他的数据不是保存在表中,而是保存在对象存储空间中。

Part25 新兴API

  • requestAnimationFrame(): 优化JS动画API,能够在动画运行期间发出信号,是浏览器能都自动优化屏幕重绘操作
  • Page VIsibility API : 让开发者知道用户什么时候正在看着页面,而什么时候页面是隐藏的。
  • Geolocation API : 在得到许可的情况下,可以确定用户所在的位置。
  • File API :可以读取文件内容。用于显示、处理、上传。
  • Web计时: 给出页面加载和渲染过程的很多信息。对性能优化非常有价值。
  • Web Workers :可以运行异步JavaScript代码,避免阻塞用户界面。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,841评论 5 472
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,415评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,904评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,051评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,055评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,255评论 1 278
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,729评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,377评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,517评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,420评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,467评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,144评论 3 317
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,735评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,812评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,029评论 1 256
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,528评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,126评论 2 341

推荐阅读更多精彩内容