[JavaScript与Web程序设计]笔记

  • 幻灯片的关键点需要完全看懂,把几个点混在一个题里面
  • 死记硬背的成分不太多,点比较小,文字长串
  • 填空的一些形式:给出程序,通过console.log()填空;
    问答有一题送分,要规整排版好,写上两三个点就差不多了;
    编程题会拿一些幻灯片的程序,看懂之后能重写;

划重点

运行js ,值和类型,typeof(null)==object, 未被赋值的变量也是undefined,声明数值中前后的0可以忽略,整数判断,NaN不和自己等,字符串,模板字符串,转义符,嵌入表达式,==obj混合考察==,delete操作符-权限,['key'],访问不存在的属性-undefined-用什么方式判断,内置类,不加new,==数组混合==,==数组那几个方法如slice==,‘use strict'不用管,先有鸡,==变量作用域==,property带记忆函数,函数参数数目,==rest参数,隐式参数==,bind,走神了漏了很多函数的没看,global.this,==箭头函数==,==运行上下文==,闭包说不用管,==词法环境==题目多,obj的方法们,遍历器很复杂,for ofspreadforEach,常识性方法们reduce,==属性描述符==,类型转换那一堆不用记但要理解,string->number(+),转换那些会有题目,|| &&, ==, ===,五六讲考不到,==页面事件处理==,HTML和CSS看明白了就行,==定时器==,==事件传播,处理,代理监听==,==异步==分值多,setTimeout 读文件 仿真怎么做 ==Generator==原理是函数运行上下文,==Promise对象==catch

基本语法与特性

  • 一个变量同时只能引用一个值,一个值可同时被多个变量引用

  • 一个==值只能具有一个类型==且不可改变,一个类型至少具有一个值

    const :不改变变量和值之间的引用关系,原子类型的值不被改变,因此效果和常引用一致

  • js中的值有七种类型

    所有原子类型的值在声明后都不会发生变化

    • null

      let a = null // 'undefined'
      typeof a // 'object' 这是一个原生bug

    • undefined

      • 只有一个值undefined,声明变量没被赋值时被缺省赋值为undefined; 对未声明变量的引用会得到错误,但是typeof是可以的(let不行)
    • boolean

      • 假 - N0fun : NaN, +0, -0, false, undefined,null,""(空字符串)
    • number

      • 控制小数位数toFixed(),控制有效数字个数toPrecision()

      • 数值相等判断用=== (Number.EPS=2^-52)

      • NaN也是number,不和任何值相等,它是唯一不和自己相等的值
        当然复合类型判断相等是看地址,所以{}!=={},[]!==[],function(){}!==function(){}

      • -1/0 === -Infinity

      • 2^ 969和1.79E308都还可以,多了就不大行了 ——数值范围不用记

      • 还有Object的方法is(a,b)编码相等,isInteger(),isSafeInteger()其实就是2^53-1含以下

        function is(v1,v2) { /*自己写判断相等函数*/
            if (v1 === 0 && v2 === 0) return 1/v1 === 1/v2 //+-0
            if (v1 !== v1) return v2 !== v2                //NaN
            return v1 === v2
        }
        
    • string

      • ES采用UTF-16的编码方式将string中的16位整数序列翻译成字符

      模板字符串前后要用括起来,可以嵌入表达式 以下显示为s='Hi,3+4=7'let a = 3, b = 4;let s='Hi,${a}+${b}=${a+b}';`

    • symbol:提供了一种存储无关的方式来表达一个符号

      • 初始动机是为obj加入private property,而在实际使用中,这作为定制/扩展系统功能的一种方式

      • 创建/使用:

        let mySymbol = Symbol("a description")       //不准用new
        let myObject = {}
        myObject[mySymbol] = "a property with a symbol key"
        let mySymoblObj = Object(mySymbol)  //用函数封装到obj里面
        let mySymbol1 = Symbol(), mySymbol2 = Symbol()
        mySymbol1 === mySymbol2               //false 永远不相同
        
        • 共享Symbol类型的值:利用全局的symbol值注册库
          let mySymbol = Symbol.for("description")
      • 在for-in语句中,不会遍历到obj里symbol类型的key

    • object(non-primitive type)

      • property(key~string/symbol,value,...)
        在没增加权限控制时,可以逐步添加属性
        点操作符只能存取key不会导致歧义的属性,而方括号都可以

          /*ES6 simplified object literal declaration*/
        let name = "shellywhen", age = 20
        let good$Girl = {name,age}
          /*former object literal declaration*/
        let normal_Girl = {name: "shellywhen", age: 20}
          /*use a inner constructor*/
        let girl = new Object()           //"new" is neccessary
        girl.name = "shellywhen"
        girl.age = 20    
        
      • built-in obj
        这和自动装箱(automatic-boxing)有关,让原子类型具有方法
        ES规定,对Number/Boolean/String不加new就是强制类型转换
        超出Array长度的赋值可能出现空洞(hole),可以修改length阶段
      • objects are truthy,如new Boolean(false) == true
  • 传值/传引用?

    根据ES规范中的文字描述,赋值语句/函数调用传的都是==引用==。

  • 一些build in object

    • Array

      • 建立:myList = ["dog", false, NaN]
        myList=new Array("dog",false,NaN)

        new Array 参数只有一个整数时,理解为整个数组长度为该值
        为避免边界行为,使用Array.of()来传入数组内容

      • 首末删改:push pop unshift shift (看字母数)
        中段删改:splice(start, deleteCount, ...item)
        取中段:slice(start = 0, end = length-1)

    • Function 既是constructor也是 b-i-o

      • let foo = new Function("a","b","return a+b")
      • typeof 一个 function obj 返回"function"
  • Prototype

    1. 每个obj相关联且仅关联一个Prototype
    2. Prototype要么是obj要么是null值

    ES规范规定,Prototype是obj的一种internal state,被存放在名为[[Prototype]]的internal slot中;

    对于一个obj,包含properties, internal slots, internal methods
    <img src="pic/ObjectComponent.png" style="zoom:30%"></img>

    obj之间通过prototype关系形成原型链,提升obj的动态性

    • 设置
      创建时关联:let obj = Object.create(proto)
      创建后关联:Object.setPrototypeOf(obj, proto)
      获得一个obj的prototype:let proto = Object.getPrototypeOf(obj)
  • 特性

    主函数可被理解为global object的一个property

    无论在程序的什么位置,只要对未声明变量赋值,改赋值语句一旦执行后该变量自动变为global object的一个property

    在源文件第一行写下"use strict"就能消灭js的常见邪恶特性

    js在运行前,通常有一个耗时几微秒的编译活动,变量的作用域在这个编译活动中形成。js更接近一种解释型语言。从效果来看,编译把作用域的变量声明提到前面。==考点区:var奇怪行为==

    • 使用function declaration声明的函数变量具有函数级(体)的作用域
    • 使用let const声明的变量具有块级的作用域(从声明处开始)

Function

function是特殊类型的object,对object做的事情对function也能做——可以赋值给变量,放到数组中,作为property的value,<u>作为参数(callback function),作为返回值</u>,为function添加property

ES6为function添加了name这个property

数组的sort方法接收一个函数,该函数接收两个值,返回二者相对位置

数组的forEach方法接受一个回调函数,该函数负责对每个元素逐个处理

let isPrime.store = isPrime.store || {}      //使用或运算符设置默认值
  • 函数参数

    • 调用函数时传递的参数数量不需要等于定义时参数的数量

    • 传入一个数组,直接在数组前加...(叫做spread操作符)

    • 参数默认值(ES6引入) let add = (a = 0, b = 0) => a+b

      let add = (a = 0, b = 1) => a+b
      console.log(add(b=2))                                  // 2
      
  • 当缺少参数时,在函数体内违背传入的参数值为undefine
    多传入的参数在函数体内通过arguments/rest参数(ES6引入)访问
    rest是未定义的剩余参数数组,arguments是所有的参数对象

    let multimax = function(a, ...remainingNumbers) {
        remainingNumbers.sort((d1,d2)=>d1-d2)
        allArgument = Array.from(arguments)       //ES6 转成数组
        return a * remainingNumbers[0]
    }
    console.log(multimax(3,8,1,7,6,5))
    
    let func = function(a,b) {      //"use strict"可消除别名特性
        let c = a
        console.log(arguments[0], a, c)
        a = 100
        console.log(arguments[0], a, c)
        arguments[0]=10000
        console.log(arguments[0], a, c)
    }
    func(1)
    
  • 调用

    • 函数上下文 function context

      • 每次函数调用,都会关联一个特定的函数上下文,即一个object或undefined值,作为一个隐式参数被传递到函数体中,对应的参数名称是this
      • 在非严格模式下,函数上下文为global object, 而在严格模式下函数上下文为undefine值
      • 用以联系起function和被赋值的property

      new.target的值为undefined,则函数调用前没有new,否则有

    • 作为函数/方法调用:命名约定首字母小写

      • 在原型链上的表现 - 函数来自远方,而this始终是当前对象
    • 作为构造函数调用:命名约定首字母大写

      • 在前面加上new关键词,以更加方便地创建多个具有足够共性的obj
      • 如果不return this则返回值正常返回,new创建的obj被忽略
    • 通过apply或call方法调用

      • 随意调用函数时的函数上下文

      • x.call(thisArg, ...args) x.apply(thisArg, argArray)
        第一个参数是调用函数上下文
        第二个参数call是以列表表示的传入参数,apply要用数组
        返回值是以thisArg为上下文,对x调用的返回值

        大概是申请了个symbol 关联方法,最后再删除

  • 其他

    • bind 方法 x.bind(thisArg, ...args)
      • 返回一个函数,行为与x完全相同;上下文被固化为thisArg;
      • ...args是绑定的参数
  • 箭头函数

    • 箭头函数不能作为构造函数,也没有this,arguments这两个隐式参数;
    • 箭头函数定义中出现的this参数在箭头函数创建时固化为当时环境中的this参数,永不再变;==function context==
  • 闭包

    • 当⼀个函数对象被创建时,同时还创建了⼀个闭包
      其中包含: 该函数、以及在此时可以访问到的所有变量
    • 用途是信息封装,只用函数才能调用
    • 实现方式:function execution context & lexical environment
      • FEC: 每一次函数调用,通常会创建一个新的函数上下文
        函数调用结束后,运行上下文通常会被抛弃
        ES程序的运行会形成由“函数运行上下文”构成的栈
      • 词法环境是专门为闭包设计的,无法显式访问
        由代码块和函数构成,代码片段的每一次运行都会创建新的词法环境
      • 当一个函数被创建时,创建这个函数的代码片段所关联的词法环境会被放到[[Environment]]的internal slot中;
        当一个函数被调用时,一个函数运行上下文被创建压到栈顶,同时为函数运行上下文创建一个词法环境,将该词法环境的外层词法环境设为该函数[[Environment]]的值

<img src="pic/ExecuteNow.png" style="zoom:60%">

Object

  • 常见方法:

    key in obj - 寻找指定的key在不在这个obj上,或者对应原型链上

    .hasOwnProperty(key) - 寻找这个key在不在这个obj上

    .getOwnPropertyNames(obj) 返回数组,包含obj所有string类型的key

    .getOwnPropertySymbols(obj) 返回数组,包含obj所有symbol类型的key

  • Iterable object:
    具有一个key为Symbol.iterator的属性,这个属性的值是一个函数,函数会返回一个iterator;包括Array, Map, Set, String, auguments

    • iterator是一个object,具有next方法,对它的一次调用返回一个obj{done, value}
    • for-of 循环语句(value)
  • Collections: Array, Map, Set
    任何可遍历的obj都可以传到new里面构造

    • Array:

      • push, pop, unshift, shift, splice(start,num,...insert), slice(start,end), indexOf(value), LastIndexOf(value), findIndex(满足条件), sort((v1,v2)=>{return v1<v2? -1: (v1>v2? 1:0)})

      • splice和slice都是返回start~end的东西

      • forEach((v,i,owner)=>{}) 是接受三个参数的;
        map接收回调函数,按顺序对每个值应用该函数将这个值变成另一个值放进新数组
        every, some

        const pets=[{name:'dog'},{name:'cat'},{name:'snake'}]
        if pets.every(pet=>'name' in pet)
          const names=pets.map(pet=>pet.name)
        // names=['dog','cat','snake']
        

        find找到第一个为止,filter把所有满足的放进数组

      • reduce

        const num = [1,2,3,4,5]
        const sum = num.reduce((sum,v)=>sum+v, 0)
        
    • Map: 任何类型的值都能作为key

      • set(key,value), get(key), size, has(key), delete(key), clear(), forEach((value,key,owner)=>{})
    • Set: 由无重复值形成的有序列表

      • add(value), size, has(value), delete(value)
  • Property Descriptor
    一个object,其中包含若干property,用于对所在property行为进行描述;使用defineProperty(obj,propKey,propDes)来修改

    <img src="pic/PropertyDescriptor.png" style="zoom:60%">

    ==考点==:configurable被置为假,在writable为true时要么可以改false要么改值,其他均不行

    • 通过getter和setter访问property
  • Prototype

    • constructor提供了基于obj引用constructor的方法

    在Javascript语言中,要是想仿真C++类的关系中,使用原型链的方式可以实现。==考点:理解例子==

    • class
    • const Person = function(name) {
        this.name = name
      }
      Person.prototype.getName = function() {
        return this.name
      }                          //Person关联的object加入一个函数
      const xie = new Person("shelly") 
      console.log(xie.getName()) //xie->对象->[[Prototype]]有这个函数
      
    class Person {
        constructor(name) {
            this.name = name
        }
        getName() {
            return this.name
        }
    }
    
    • extends
    class Mammal {}
    class Person extend Mammal (){
        constructor() {
          //  ...
        }
        getWeight() {
            return super.getWeight
        }
    }
    
    • instanceof: 判断一个obj是否在某个构造函数的原型链上
  • 析构操作

    • 一些例子

      /*对Object的析构*/
      let node = {
          type: "identifier"
          name: "foo"
          loc: {
              start:{
                  line: 1
                  coloum: 2
              }
          }
      range:[startIndex]
      }
      let {type, name} = node  //要有=,不能=undefined/null
      ({type, name} = node)    //提取obj型函数参数的特定property
      let {name: localname = "bar"} = node //缺省 不同名
      let {loc:{start:{line}}, range:[startIndex]} = node
      
      /*对Array的析构*/
      let colors = ["red", undefined,"blue",["pink","yellow"]]
      let [1st, 2ed = "grey"] = colors
      let [, , 3rd] = colors
      let [,,,[,4in]] = colors    //"yellow"
      let [5th, ...rest] = colors
      
      /*变量值交换*/
      let [1st, 2ed] = [1st, 2ed]
      
      /*优秀例子*/
      function setCookie(name, value, {secure, path} = {}){
          secure = 1 - secure
      }
      

类型转换

这节太复杂了,自己看课件算了

很多时候,javascript会以显式/隐式的方式将一种类型的值转换为另一种类型的值;ES6定义了一组抽象操作;

  • 一组抽象操作(看课件,内容过多)
    • ToPrimitive(input, preferredType)
    • OrdinaryToPrimitive(input, prefferedType)
    • ToBoolean(input) - N0fun
    • ToNumber
    • ToString
    • ToObject
  • && || 的行为
  • == 抽象相等,比较过程中允许类型转换; ===严格相等,比较过程中不允许进行类型转换。

Web页面编程

Html内容, CSS形式, JavaScript行为 -> DOM树

  • 元素选择和修改

      `preventDefault()` 防止href为空时的跳到新页面的缺省行为
    

    getElementById getElementsByTagName getElementsByClassName

document.addEventListener("DOMContentLoaded",()=>{
    const div = document.querySelector("div")
    console.log(div.style)
})

getAttribute setAttribute(attr,value)

​ CSS信息以嵌入式或链接式样式表中的信息时无法直接从元素中获得

window.getComputedStyle(ele).getPropertyValue(propNameStr)

​ 对于样式表里面的内容加入 !important 可提高优先级,避免被改动

  • [Web页面的事件处理流程] 当处理完一个宏任务后,会立刻按序处理所有的微任务,知道所有微任务都被处理完后才会处理下一个宏任务;如果可能,浏览器会确保每秒60帧,一个宏任务及其所产生的微任务应能在16ms完成

  • 定时器

    const id = setTimeout(func,delay) 延迟delay毫秒把事件加入函数队列

    setInterval(func,delay) 每间隔delay毫秒便尝试将事件加入函数队列,当任务队列中还存在未处理的同源interval事件时interval对应函数时不会加入队列

    clearTimeout(id) 函数尚未被触发时取消定时器行为

  • Web页面中的事件处理

    • 处理计算密集型操作

    • 事件在DOM中的传播:默认捕获从外向内,冒泡从内向外。

      • addEventListener(type,func,useCapture)
        useCapture默认是假,事件冒到它才会调用,否则监听了就调用了

        const tb = document.querySelector("tbody")
        tb.addEventListener("click",function(e)){
          if(e.target.tagName.toLowerCase()=="td")
          e.target.style.backgroundColor = "yellow"
        }  //e.target是事件发生在的html元素
        
    • 自定义事件const Myevent = new CustomEvent(eventType, {detail: eventDetail})

Js异步编程

  • 如果一个任务处理函数用时过长,会降低整个应用的并发程度或处理效率。为了提高程序的并发程度或处理效率,需要异步编程。情境:计算密集,IO密集。

    • 将计算密集型任务拆分为一组细粒度的子任务(例如表格拆分定时创建,在完成一个子任务后,把下一个子任务加入任务队列setTimeout(nextTask,0)
    • 使用异步读取文件或异步接收网络数据的函数。在启动IO任务时传入回调函数;然后程序不必阻塞等待IO任务完成,而是继续执行后面的代码。当IO任务完成后,把IO完成事件加入任务队列。
  • Generator函数

    • 把函数本身做的事分为小的块,由关键词yield来控制。
    • 可以视为一个状态机。
    • return的值存在遍历器的value里面。
    function * likes(){
        while(true)
          yield "likes"
    }
    function * PersonGenerator(){
        yield "shelly"
        yield * likes()
        yield "gary"
    }
    for (let person of PersonGenerator()) 
        console.log(person)
    
    • 与Generator函数进行双向通讯

      • 通过next()从generator函数获得数据,通过next()的参数向generator传入数据
      • 向generator函数抛入异常;
      let [a,b,c]=yield "hello"
      let rst = 
      
      
  • Promise对象

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

推荐阅读更多精彩内容