热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

js知识梳理

jsjs初级数据类型基本数据类型String,Number,Boolean,Null,Undefinedundefined定义未赋值;null定义并赋值为null,可以用于对象初始




js

在这里插入图片描述


js初级


数据类型


  • 基本数据类型


    • String, Number, Boolean, Null, Undefined


      • undefined定义未赋值;null定义并赋值为null,可以用于对象初始化,也可用于垃圾回收 释放内存
  • 引用数据类型(对象)


    • Object(特殊的Array, Function)


      • 通过包装类String(), Number(), Boolean()将基本数据类型变成Object。Object类型创建要new
      • 引用数据类型可以 添加属性;Object之间不能比较,因为会比较他们两的内存地址
      • let a = {}; a[0]=1; a[1]=2; console.log(a); //{ 0:1, 1:2 } 类似伪数组,以下标作为key
    • 调对象的属性 .属性/[“属性名”],属性名包含特殊字符(空格,-)或者不确定(变量名在变量里)时 必须第二种


      • let pp = {}; let pName = “myName”; let value=“yl”; pp[pName] = value; pp.myName; //“yl”

false的情况


  • undefined, null空指针(类型object), false, 0, “”(空串且没有空格), NaN(无法计算结果时出现,非数值,但是typeof NaN === “number”)
  • 已声明的对象,数组都为true

this



    1. test():window 以函数形式调用时,this永远是window

    • 任何函数本质上都是通过某个对象来调用,若没有直接指定 就是window

    1. p.test():p 以方法形式调用时,谁调用this就是谁

    • 方法:obj.属性名 = function(){ };obj.属性名();调方法 //当属性值为函数,那么属性名为方法

    • 例如:inner.Onclick= function(){console.log(this)} ; this就是inner(若inner是一个dom对象),这个回调函数作为inner的onclick属性的方法


      • 不能用箭头函数,箭头函数this会变成window

    1. new test(): 新建的对象 以构造函数形式调用时,this是新创建的对象(实例)

    • 构造函数(类):函数无返回值,调用时需new;将新建的对象作为返回值;新建的对象(实例)设置为函数中的this

    1. p.call(obj):obj 使用call和apply调用时,this是指定的那个对象 js05_04, 即调用函数时,fun.call(xxx), xxx会传给fun的this;区别于直接fun() 调函数this永远是window

    • 同:call/apply可用于修改函数执行时的this
    • call:fun.call(obj, 实参1, 实参2). 第一个参数是修改this, 后面跟的参数可以传入fun作为实参
    • apply:fun.apply(obj, [实参1, 实参2]) apply要将实参放在数组里传

DOM


  • document object model

  • onload


    • onload事件在整个页面加载完后触发
    • 可以实现将js写在html之前
  • DOM查询


    • 基本


      • getElementById, getElementByTagName, getElementByClass(兼容问题)


        • 查询时innerHtml获取标签,innerText自动去除标签
        • 注意:getElementsByTagName等输出的是数组,需要取[0]
      • 分类:文档节点—— 元素节点—— 属性节点—— 文本节点

    • 子节点


      • childNodes, firstChild, lastChild


        • childNodes查询包括文本节点的所有节点,而标签间空白换行也会当作文本节点;对比children,只获取当前的子元素
        • 同理 firstChild会包含空白文本,firstElementChild不包含,但低版本不兼容
    • 父节点和兄弟节点


      • parentNode, previousSibling, nextSibling


        • previousElementSibling等
    • html, body


      • 直接document.body/ html
    • 查询选择器querySelector


      • document.querySelector(".box img") 可以直接输入css选择器,很强大,可代替基本查询

      • 但是,只能返回一个元素,若查询有多个只返回第一个


        • document.querySelectorAll() 兼容问题
  • 增删改查



      • appendChild在队尾添加,父元素.insertBefore(new, a)在a前面添加new,但只能添加一次

      • removeChild

      • insertChild

      • 增删改一定要知道父元素,可以 .parentNode查询到父元素再增删改
  • 修改css样式


    • 元素.style.样式名 = 样式值


      • [样式名] / -变成驼峰命名
    • js通过内联进行修改,如果原来有!important会失效

    • 只读样式


      • getComputedStyle


        • IE不可用


          • getComputedStyle(element,false).width
          • 带px
      • currentStyle


        • 只有IE可用
      • getStyle(element, “width”)


        • 输出xxpx, 可以parseInt(getStyle(element, “width”)) 取出字符串中的合法数字
      • scrollWidth, client, offset等可查询且只是数字


        • scroll只有内容,client包括padding, offset包括border
      • 注:想要js读取css样式表的值,一定要把css写在js前面

  • 事件


    • 冒泡


      • 如,给祖先,父元素,子元素都绑定点击alert事件;将会遵循子元素,父元素,祖先元素的顺序依次冒泡显示
      • 可用关闭冒泡,一般都有用
    • 委派


      • 如:通过js新建的元素不具备点击事件,可用在其父元素中添加点击事件,其所有子元素都能获得

      • 如果想要其他元素不被委派到事件,可以给需要的元素加class,然后判断


        • if( event.target.className == “xxclass”)
        • event.target替换this也行,都是inner dom对象
    • 绑定


      • 内联


        • 在html元素中写οnclick=“xx”, 然后在js中声明
      • js中 dom对象.事件 = 函数


        • 如:document.Onclick= (event)=>{ console.log(event) }
        • 可传参event(当前的事件对象 点击事件就是PointerEvent,鼠标事件就是MouseEvent), 对点击事件event处理
        • 此方法不可绑定多个函数,下面的会覆盖上面的
      • addEventListener监听


        • inner.addEventListener( “click”, function(){ console.log(111), false} )


          • 参数:1. 绑定什么事件,不加on; 2. 回调函数,事件触发时该函数被调用 ;3. 是否在捕获阶段触发事件,一般false

          • this是inner


            • attachEvent中this是window
        • 此方法可以为同个元素的相同事件 绑定多个响应函数,依次触发,不会被覆盖

        • Ie8以下兼容用attachEvent, 循序要反,两个参数,事件加on


          • 可写一个bind函数解决兼容,传三个值, 绑定事件的对象,绑定什么事件,回调函数


            • function bind( obj, eventStr, callback)

BOM


  • browser object model


    • 包含:window, navigator, location, history, screen

    • window


      • 代表整个浏览器窗口,window是网页的全局对象
      • 保存在全局作用域中的变量都会作为window的属性保存, 在全局作用域中的对象都会作为window的方法保存
    • navigator


      • 代表浏览器信息,识别不同浏览器

      • 一般只使用userAgent判断浏览器信息(userAgent用户代理==浏览器)


        • 结合正则表达式判断/Chrome/i.test(navigator.userAgent), 比较复杂的new RegExp
    • Location


      • 代表当前浏览器的地址栏信息

      • 区分大小写。大写L返回一个函数

      • 常用方法


        • assign()也是跳转,和直接赋值一样
        • reload()同刷新,用于重新加载页面,reload(true)强制清空缓存
        • replace()替换,也是跳转,但是跳转完回不去,不会生成历史记录
    • History


      • 浏览器的历史记录,可操作

      • 由于隐私原因,该对象不能获取到具体的历史记录, 只能操作浏览器向前向后翻页


        • 而且只有当此访问有效
      • 属性


        • length访问了几个页面
        • back()作用同浏览器回退按钮;forward()跳转下一个
        • go(整数)跳转到指定页面,1 向前跳转一个页面
    • sreen


      • 获取用户显示器的相关信息,移动端用 进行适配

定时器


  • setInterval


    • setInterval(function() {}, xxxxms)

    • 参数:1. 回调函数,每隔xxxx调用一次 2. 调用时间间隔

    • return:返回一个Number作为定时器唯一标识,第几个定时器

    • 注意


      • 将定时器写在点击事件内,一定要在开启前clear清除上一个定时器


        • 看练习js_定时器&移动
  • setTimeout


    • 只执行一次 定时调用

js高级


判断


  • typeof


    • 输出字符串
    • 可判断类型:“number”, “undefined”, “string”, “object”(null) ,“function”(例外)
    • 不能判断null于object, Array与object
  • instanceof


    • 判断实例是否属于一个构造函数
    • 可以用来判断一个对象的具体类型,Array? Function?
  • ===


数据传递盲点


  • let a = {age:1}; function fn(obj) { obj = {age: 2}}; fn(a); console.log(a.age); //2


    • 此时a原来存的地址已经失效,被赋值了新的地址,指向堆空间
  • ** let aa = 1; function fun(a) { a++}; fun(aa); console.log(aa); // 1


    • 数据有读写,只有赋值时为写。这里读取aa变量的值1,传入fun, 处理完后,fun中的形参a销毁(函数执行时创建内存,执行完a立刻释放,函数间隔一会儿 释放内存),aa不变,未被写入。如果是传入对象就可以对对象进行操作了,传值无效
  • **let p={name:“yl”, setName: function (name){this.name = name} }; p.setName(“tang”); console.log(p.name); //“tang”


    • 很常用,用于修改属性值。方法(函数作为属性 )的形参要与其他属性名相同,因为方法的this指向调用这个方法的对象,用于改变属性值
  • js调用函数时传递变量参数时,是值传递还是引用传递?


    • 理解1 值传递(基本/地址);理解2 值传递或引用传递(地址值)

函数初级再识


  • 函数的功能


    • 复用;封装,提高可读性
  • 函数的调用方式


    • test() 直接调用

    • obj.test() 通过对象调用,为方法

    • new test() //new调用,为构造函数

    • **test.call/apply(obj) //类似obj.test(),临时让test成为obj的方法进行调用,改变test的this指向obj


      • 例如:let obj ={}; function test() {this.xxx = “yl” }; test.call(obj); console.log(obj.xxx) //“yl”
        按理说,obj没有这个方法,这样就能实现obj.test()的功能
  • 什么是回调函数



      1. 你定义的 2.你没有调 3.但最终执行了
    • 常见的回调函数:1.dom事件回调函数:dom元素.Onclick= function() {} 2.定时器回调函数: setTimeout(function (){ }, 1000) 3.ajax请求回调函数 4.生命周期回调函数
  • 立即执行!


    • 又称匿名函数自调用 (function () { let a=1; console.log(a)})()

    • a不会污染全局

    • 注意() , [] 前后语句一定要加;不然会报错


      • []场景,[1,2].foreach…前面不加;报错

函数高级


  • 原型与原型链


    • 原型


      • 原型上的方法是给实例对象使用的,所以一般我们会给构造函数的prototype添加属性 以供实例访问


      • 分类


        • 显示原型


          • 每个函数都有 ,即prototype属性


            • 定义函数时自动添加,默认为空object对象
        • 隐式原型


          • 每个实例对象都有,即__proto__


            • 创建实例时自动添加,默认值为其构造函数prototype的属性值。即Fn.prototype === fn.proto


            • 同个构造函数创建的实例的原型相等p1.proto===p2.proto===P.prototype

          • ES6之前不能直接操作

    • 原型链


      • 隐式原型链:访问一个对象的属性时,先在自身属性中找,没有再沿着__proto__这条链向上查找,最终没有找到则返回undefined(注意不会报错)


        • 总结
      • 三个特性


        • 读取对象属性值时,自动到原型链中找
        • 设置对象属性值时,若当前对象没有此属性,直接添加此属性,不会碰原型链
        • 一般在原型中定义方法,通过构造函数在对象自身定义属性
  • 执行上下文与执行上下文栈


    • 变量提升与函数提升


      • 变量提升


        • var a=3; function fn(){console.log(a); var a=4 } fun(); //undefined


          • 函数内var a; 声明提前了
      • 函数提升


        • fun()函数调用 可以写在声明前面。必须function fun(){}这样定义


          • 注意:如果函数声明var fun = function(){}; 这样声明的话,首先遵守变量提升,就不能提前调用了

          • 报错,类似于var c; function c©{…}; c=1; c(2);


            • 因为变量提升先于函数提升,然后赋值操作会在提升后执行,此时c是一个数,所以报错
    • 执行上下文


      • 函数内的arguments,是一个伪数组,存放传入的实参列表

    • 执行上下文栈

  • 作用域与作用域链


    • 作用域


      • 分类:全局,局部,块级(ES6刚有)


        • 块级:if(1){let a=10}; console.log(a); //报错


          • 直接声明let a不会污染全局,不能通过window.a访问,但是var可以
          • 在块级作用域中查找时,先在块级作用域中找,找不到再到全局中找
      • 面试题


        • 会报错,要访问fn2要加this

    • 作用域链


      • 一层一层,由内向外地查找
  • 闭包


    • 如何产生


      • 当一个子函数引用了父函数的变量/函数时,就产生了闭包
      • 条件:1.函数嵌套 2.内部函数引用了外部函数的数据(变量/函数)
    • 什么是闭包


      • 理解一:闭包是嵌套的内部函数(chrome调式工具查看)
      • 理解二:包含被引用变量/函数的对象
      • 注:闭包存在于嵌套的内部函数中
    • 作用


      • 延长了局部变量的生存周期


        • 闭包产生:内部函数定义时(不是调用时);闭包的死亡:嵌套的内部函数成为垃圾对象时=null
      • 函数外可以操作内部数据

    • 问题


      • 1.函数执行完,函数内部的局部变量是否存在?


        • Q:一般不存在,在闭包中的变量才可能存在(不能成为垃圾对象,必须被引用)
      • 2.在函数外部能否直接访问函数内部的局部变量?


        • Q:不能,但通过闭包可以让外部操作它
    • 例子


      • 简单的demo

      • 应用1:函数外部操作函数内部的数据


        • 利用闭包,此时函数外部就可以操作函数内部的数据

        • fn1(); //没有输出,因为fn2已经成为立即对象

        • 闭包要死亡:f = null;

        • 还要注意函数的定义的方式,定义执行完才产生闭包

      • 应用2:定义JS模块


        • 使用


          • *一个具有特定功能的js文件

          • *将所有的数据和功能都封装在一个函数内部 (私有的)

          • *只向外暴露一个包含n个方法的对象/函数(return)


            • 想暴露两个或以上函数,可以return{ one: one, two: two}


              • let module = myModule(); module.doSometing()
            • 也可以把函数放在window属性中,做成一个立即执行函数


              • 导入的js模块。使用时直接myModule2.doSomething()
          • *模块使用者,只需要通过模块暴露(return)的对象调用方法实现对应功能(let xx = 函数;xx())

    • 缺点


      • 函数内局部变量没有被释放,占用内存时间变长

      • 容易造成内存泄漏


        • 注:内存溢出(程序运行错误或超出剩余内存);内存泄漏(占用内存没有及时释放,内存泄漏积累过多可能内存溢出,常见:多余的局部变量,没有及时清理的计时器或回调函数,闭包)
      • 解决:*能不闭包就不闭包 *及时释放(闭包函数=null)

    • 面试题


      • 不是闭包


        • object.getNameFunc执行完后得到的是函数,所以调函数this是window,输出全局的name

        • 对比。是闭包(函数嵌套,且内部函数引用了外部函数的变量that)


          • *(常用)因为this会变,将this用that在函数内存起来,就可以使this还保留为调用它的对象

对象高级


  • 对象创建模式


    • object构造函数模式(场景:创建时不确定对象内部的数据,可以动态添加或修改属性/方法)


      • let p = {}; p.name = ‘yl’; p.setName = function(name) {this.name = name}; 缺点:语句太多


        • 优化:let p = {name :‘yl’; setName : function(name) {this.name = name} };
      • 问题:创建多个对象时,代码重复,适用创建单个对象

    • 工厂模式(了解工厂函数)


      • function creatPerson(name) {let obj = {name:‘name’, setName: function(name){this.name = name} } return obj} //返回一个对象的函数,即工厂函数


        • 创建两个人:let p1 = creatPerson(‘yl’); let p2 = creatPerson(‘tang’)
      • 优点:创建多个对象;缺点:对象类型都是Object,没有具体类型

    • 自定义构造函数模式(最常用)


      • function Person(name,age) {this.name = name; this.age = age; this.setName = function(name){this.name = name }}


        • 创建:let p1 = new Person(‘yl’, 4);
      • 缺点:每个对象(实例)都有相同的数据,浪费内存


        • 解决:把例如setName放到object原型中,共用


          • 在构造函数中只初始化一般函数

          • Person.prototype.setName = function(name) {this.name = name} //把方法放到了原型上,其他不变



              • 最常用
  • 继承模式


    • *原型链继承


      • 此时子类型就从继承的原型链上拿到了’Supper property’


        • 分析(好好理解,难)


          • 此时sub.constructor //Supper; 需要sub.prototype.cOnstructo= Sub
    • 借用构造函数继承


    • 组合继承


      • 最终结合体

进程机制与事件机制


  • 进程与线程


    • 进程


      • 程序一次执行,所占有的独有的一片内存空间,可通过任务管理器查看
    • 线程


      • 是进程内的一个独立执行单元;是程序执行的一个完整流程;是CPU的最小调度单元


        • 若一个程序,有两个进程,然后每个进程都只能启一个线程,那么这个程序是多进程、单线程的
      • 多线程


        • 优点


          • 提高CPU的利用率
        • 缺点


          • 创建多线程开销
          • 线程间切换
          • 死锁与状态同步
      • JS是单线程


        • 在H5中Web Workers可以多线程运行
        • 浏览器是多线程运行的,可以多进程可以单进程
    • 相关知识



其他


  • 浏览器内核


    • 内核组成模块
  • 再识定时器


    • 定时器不能保证真正定时,比如会被alert停下
  • JS的单线程


    • 代码分类


      • 初始化代码、回调代码
    • 执行基本流程


      • 先执行初始化代码


        • 包含特殊的代码



            • 设置定时器

            • 绑定事件监听

            • 发送ajax请求
      • 然后在某个时刻才会执行回调代码(异步执行)

    • 为何是单线程


      • 要与用户交互,操作dom,多线程可能带来复杂的同步问题(比如同时点击改和删,先执行删就会报错)
  • 事件循环模型


    • jS模块在主线程,定时器模块等在分线程执行的

    • 事件的回调函数和定时器等回调代码 被事件管理模块WebAPIs 放在callback queue中,待处理,等初始化代码执行完才循环遍历队列执行


      • 事件驱动模型


        • 其他相关概念


      • 事件管理模块WebAPIs包含:定时器、Dom事件、Ajax

  • H5 Web Workers(多线程)




推荐阅读
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • LeetCode笔记:剑指Offer 41. 数据流中的中位数(Java、堆、优先队列、知识点)
    本文介绍了LeetCode剑指Offer 41题的解题思路和代码实现,主要涉及了Java中的优先队列和堆排序的知识点。优先队列是Queue接口的实现,可以对其中的元素进行排序,采用小顶堆的方式进行排序。本文还介绍了Java中queue的offer、poll、add、remove、element、peek等方法的区别和用法。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • Android JSON基础,音视频开发进阶指南目录
    Array里面的对象数据是有序的,json字符串最外层是方括号的,方括号:[]解析jsonArray代码try{json字符串最外层是 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
author-avatar
薛薛Sying
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有