javascript学习笔记(不是很精 但是很多)

406 阅读9分钟

前言

首先声明一下这篇文章是我平时学习搜集网上的各个文章学习的一些笔记,如果冒犯了哪位大神或说抄袭了哪位大神,先给您陪个不是了,因为jacascript这些知识来来回回就这么些东西,多少有点冲突,写这些只是为了以后自己用的时候可以用,就当做复习了,如果有小伙伴想补充的,欢迎留言。好了,废话不多说。

js基础

执行过程

JavaScript 运行分为两个阶段:

  • 预解析
    • 全局预解析(所有变量和函数声明都会提前;同名的函数和变量函数的优先级高)
    • 函数内部预解析(所有的变量、函数和形参都会参与预解析)
      • 函数
      • 形参
      • 普通变量
    • 执行

数值

  • Number: 包括浮点数,NaN,Infinity表示无穷大也是number类型。
  •   NaN === NaN;//false 
      isNaN(NaN);//true 
      false==0;//true
      false===0;//false
      0 => false
      "" => false
      undefined => false
      null => false
      NaN => false
      undefended 和 null相等但是不全等。
    

布尔

Bollean:turefalse,true代表真,通常用来判断条件成立,false代表假。

Null

Null:表示空,不解释。

Undefined

Undefined:表示未定义。(通常控制台里见到的比较多

字符串

String:声明的方式有单引号和双引号,双引号可以解析一些特殊的字符。字符串常用的一些方法我就不写了百度一搜一大把,大家可以记住几个常用的api(不过有一点大家要记住字符串具有不可变性,(当然不是真的不能改,比如你非要用一些不要脸的方法。。。))。

  • 截取字符串 abcdefg 的 efg: alert('abcdefg.substring(4)').

  • 字符串的常用方法:

  •   charAt() // 获取指定位置处的字符
      concat()  // 拼接字符串,等效于+,+更常用
      substring() // 从start位置开始,截取到end位置,end取不到
      substr() // 从start位置开始,截取length个字符
      indexOf() // 在字符串中查找指定字符,如果找到返回位置,找不到返回 -1 
      trim() // 去除字符串两边的空格
      split() // 将字符串分割成数组
      toUpperCase() 	// 将字符串转换为大写
      toLowerCase() 	// 将字符串转换为小写
    

数组

Array:数组,声明的两种方式:var a = [1,2,3]; var a = new Array(); (api可以百度搜一下,记不住也没关系,用的时候查就好了,好吧,我准备好了);

  • 交换两个变量的值:

  •   var a = 10; var b = 20;
      var [a,b] = [a,b];
    
  • 数组的解构赋值:

  •   var arr = [1, 2, 3]; 
      (1)var [a, b, c] = arr; 
      (2)var [a, b] = arr;
      (3)var [a, , c] = arr; 
      (4)var [a, b, c, d] = arr;
    
  • 数组的常用方法:

  •   // push() 向数组末尾追加数据
      // pop() 从数组末尾删除数据
      // unshift() 向数组最前面追加数据
      // shift() 从数组前面删除数据
      // splice() 数组的万能方法(重要) 删除,替换,添加
      // indexOf() 从数组中查找数据 找到返回下标 没找到返回 -1/ / 数组方法indexOf() 在ie9以下不支持
      // forEach() 遍历数组
      // join() 将数组中的数据以某个连接符进行连接 返回连接好的字符串
      // sort() 数组排序
      // concat() 数组拼接
      // reverse() 翻转数组
    

Math

Math对象不是构造函数,对象内部提供了和数学相关的属性和方法
    Math.PI						 // 圆周率		
    Math.floor() / Math.ceil()	  // 向下取整/向上取整
    Math.round()				 // 取整,四舍五入
    Math.abs()					// 绝对值
    Math.max() / Math.min()		 // 求最大和最小值
    Math.random()                // 生成随机数
    Math.round(Math.random()*(y-x)+x)  // 返回从x到y之间的随机数

日期时间 Data

// 通过内置的Date构造函数可以创建日期时间对象,可以通过对象下面的方法获取当前时间。
    var dt = new Date(); // 创建日期时间对象
    dt.getFullYear(); // 获取年份
    dt.getMonth(); // 获取月份(0~11)
    dt.getDate(); // 获取日期
    dt.getDay(); // 获取星期(0~6)
    dt.getHours(); // 获取小时
    dt.getMinutes(); // 获取分钟
    dt.getSeconds(); // 获取秒
    var dt = new Date();
    // 返回基于1970年1月1日(世界标准时间)起至现在的毫秒数。
// 设置时间
    // 语法:new Date(年, 月, 日, 时, 分, 秒)
    var dt = new Date(2000, 1, 1, 0, 0, 0);
    dt.getFullYear(); // 2000

对象

Object:对象,这里的对象指的不是异性,它是由一组键值对组成的无序的集合,var obj = { name: 'zhangsan',age: 18 }; 调用的时候前面属性后面值 obj.name

  • 对象的结构赋值:
  •   var obj = {
          name: '老王',
          age: '39'
      };
    
      写法1
      var { name, age } = obj;
      console.log(name, age);
      
      // 写法2
      去obj中找到name的值赋值给newName,后续使用newName这个变量
      var { name: newName, age: newAge } = obj;
      var { name: newName, age: newAge } = {
          name: '老王',            
          age: '39'
      };       
      console.log(newName, newAge);
    

函数

Function: 函数,有两种方式:

  • (1)函数声明:function (参数1,参数2) {};

  • (2) 表达式:var fn = function () {};

  • arguments 是函数形参的集合,是一个伪数组 函数扩展:

    1. 函数参数可以指定默认值
  •            function fn2(x = 10,y) {
                   return x;
               }
    
    1. 函数参数是惰性求值
  •       var i = 10;
          
          function fn3(p = i + 1) {
               return p;
          }
           两次输出结果一样
           console.log(fn3());
           console.log(fn3()); // 好吧,知道你们懒(手里-敌军还有三秒抵达战场)所以呢我已经打出来了,两个都是(11)。
    

运算符

运算符:

  • 算数运算符:+ - * / % 。(最后这个句号可不是。。。。)

  • 一元运算符:++(自身加一,前置++先自增,后置++先运算完在自加) --(自身减一)。

  • 逻辑运算符:&& || !又被称为与或非

  • 比较运算符:< > <= >= ==(会比较两边的值) != ===(会比较两边的类型和值) !==

  • 常用的三元 语法:条件表达式 ? 表达式1 : 表达式2

  • 赋值运算符:+=(自身加xx) -= *= /= %=

  • 运算符的优先级:() > 一元运算符 > 算数运算符 > 关系运算符 > 相等运算符 > 逻辑运算符 > 赋值运算符;

循环

循环: if-else-if(常用) ; switch; while; do...while; for(常用);

预解析

预解析: 学习预解析可以帮我们解决什么问题? // 问题一 console.log(num); // ? var num = 10; console.log(num); // ?

    // 问题二
    fn (); // 为什么函数调用可以在函数声明之前?
    function fn () {
        alert('fn函数被执行了');
    };
    • 预解析过程:

      • 在全局作用域下查找var和function关键字
      • 对于变量,浏览器会将它放在内存中并赋值为undefined
      • 对于函数,浏览器会将函数整体放在内存中
    • 代码执行过程:

      • 逐行执行,遇到变量,为变量赋值
      • 遇到函数声明,略过。
      • 遇到函数调用,形成函数局部作用域,在函数局部作用域内部发生预解析和代码执行,完成后跳到函数调用代码的后面,- 继续进行全局作用域下的代码执行过程。

      案列:

        (1) console.log(fn);
        fn ();
        var fn = function () {
            alert('我执行了吗?')
        }
        
        (2) var num = 10;
        fun();
        function fun() {
          console.log(num);
          var num = 20;
        };
        
        (3) var num = 1;
        function fn1(num){
            alert(num);
            num = 2;
        }
        fn1(num);
        alert(num);
        
        (4) fn ();
        function fn () { console.log(1) }
        fn ();
        var fn = 10;
        fn ();
        function fn () { console.log(2) }
        fn ();
                    (5) alert(a);
        alert(fn);
        var a = 1;
        function fn(){ 
            return false;
        };
      

this

  1. 在全局作用域下,this指向window对象。
  2. 在局部作用域下,函数内部中this的指向,要在函数调用的时候才能确定,函数前面是谁,this就指向谁。
  3. 构造函数中的this,指向新创建的对象。

面向对象

特性:封装,继承,多态。

知乎:如何用一句话说明什么是面向对象思想?

原型

  • Javascript 规定,每一个构造函数都有一个 prototype 属性,指向另一个对象。 这个对象的所有属性和方法,都会被构造函数的实例继承。 这也就意味着,我们可以把所有对象实例需要共享的属性和方法直接定义在 prototype 对象上。

      function Person (name, age) {
        this.name = name
        this.age = age
      }
      
      console.log(Person.prototype)
      
      Person.prototype.type = 'human'
      
      Person.prototype.sayName = function () {
        console.log(this.name)
      }
      
      var p1 = new Person(...)
      var p2 = new Person(...)
      
      console.log(p1.sayName === p2.sayName) // => true
    

继承

  • 借用构造函数继承

  •   function Person (name, age) {
        this.type = 'human'
        this.name = name
        this.age = age
      }
      
      function Student (name, age) {
        // 借用构造函数继承属性成员
        Person.call(this, name, age)
      }
      
      var s1 = Student('张三', 18)
      console.log(s1.type, s1.name, s1.age) // => human 张三 18
    

    原型继承

  •   function Person (name, age) {
           this.type = 'human'
          this.name = name
          this.age = age
      }
    
      Person.prototype.sayName = function () {
      console.log('hello ' + this.name)
      }
    
       function Student (name, age) {
      Person.call(this, name, age)
      }
    
  • 利用原型的特性实现继承

     Student.prototype = new Person()
    
      var s1 = Student('张三', 18)
    
     console.log(s1.type) // => human
    
     s1.sayName() // => hello 张三
    

闭包

  • 闭包 就是将函数内部和函数外部连接起来的一座桥梁。

  • 事例1:

  •   var arr = [10, 20, 30]
    
      for(var i = 0; i < arr.length; i++) {
      arr[i] = function () {
      console.log(i)
      }
      };
    
  • 事例2:

  •       console.log(111)
    
          for(var i = 0; i < 3; i++) {
      
           setTimeout(function () {
               console.log(i)
          }, 0)
          }
           console.log(222)
    

正则

  • \d : 匹配数字

  • \D : 匹配任意非数字的字符

  • \w : 匹配字母或数字或下划线

  • \W : 匹配任意不是字母,数字,下划线

  • \s : 匹配任意的空白符

  • \S : 匹配任意不是空白符的字符

  • . : 匹配除换行符以外的任意单个字符

  • ^ : 表示匹配行首的文本(以谁开始)

  • $ : 表示匹配行尾的文本(以谁结束)

  • ? : 重复零次或一次

  • {n} : 重复n次

  • {n,} : 重复n次或更多次

  • {n,m} : 重复n到m次

  • [] 字符串用中括号括起来,表示匹配其中的任一字符,相当于或的意思

  • [^] 匹配除中括号以内的内容

  • \ 转义符

  • | 或者,选择两者中的一个。注意|将左右两边分为两部分,而不管左右两边有多长多乱

  • () 从两个直接量中选择一个,分组 eg:gr(a|e)y匹配gray和grey [\u4e00-\u9fa5] 匹配汉字

  • 验证手机号:^\d{11}$

  • 验证邮编:^\d{6}$

  • 验证日期: 2012-5-01: ^\d{4}-\d{1,2}-\d{1,2}$

  • 校验密码强度: 密码的强度必须是包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间。 var reg = /^(?=.\d)(?=.[a-z])(?=.*[A-Z]).{8,10}$/;

  • 校验中文: 字符串仅能是中文。 var reg = /^[\u4e00-\u9fa5]{0,}$/;

  • 由数字、26个英文字母或下划线组成的字符串 var reg = /^\w+$/;

  • 校验身份证号码: 下面是身份证号码的正则校验。15 或 18位。

  • 15位: var reg = /^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$/;

  • 18位: var reg = /^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/

  • 校验金额: 金额校验,精确到2位小数。 var reg = /^[0-9]+(.[0-9]{2})?$/;

  • 匹配手机号码的正则表达式:/;^1([358][0-9]|4[579]|66|7[0135678]|9[89])[0-9]{8}$/;

type返回类型

  • javascript中typeof返回的数据类型有那些
  • alert(typeof[1,2,3]); // object
  • alert(typeof 'Hellow word'); // string
  • var i = true; alert(typeof i); // boolean
  • alert(typeof 1); //number
  • var a; alert(typeof a); // undefined
  • function () {}; alert(typeof a); // function

节点 ,方法

  • appendChild(); 添加
  • insertBrfore(); 添加到元素前面
  • removeChild(); 移除
  • replaceChild(); 修改
  • createDocumentFragment(); 创建一个DOM片段
  • createElement(); 创建一个具体元素
  • createTextNode(); 创建一个文本节点
  • getElementByTagName(); 通过表签名获取元素
  • getElementsByName(); 通过元素的 Name 属性值
  • getElementById(); 通过元素 id

window.onload 和 document ready 的区别

  • window.onload 是在 dom 文档树和所有文件加载完之后执行一个函数,只能出来一次。
  • document ready 原生没有这个方法,jquery 中有$().ready(function),在 dom 文档树加载完之后执行一个函数(文档树加载完不代表全部文件加载完)。

javascript 时间流模型

  • **事件冒泡:**子元素的事件逐渐向父元素传播。
  • **事件捕获:**父元素的事件逐渐向子元素传播。
  • **DOM事件流:**事件捕获,目标阶段,事件捕获。

列举 4 个DOM 和 5 个对象常用的方法

  • 对象: windowing,document, location, screen, history。
  • 方法: alert(), confirm(), open(), close()。

iframe 的优缺点

优点

  • 并行加载脚本。

  • 解决加载缓慢的第三方内容问题。 缺点

  • 会组织页面的 onload 事件。

  • 即使内容为空,加载也需要时间。

  • 没有语义。

Cookie 的理解

  • Cookie 的长度和数量限制,长度超过 4kb 会被截掉。
  • 安全问题,数据会暴露在 url 上面。

js 延时加载的方式

  • async
  • 动态创建DOM
  • 按需异步引入 js

document.write 和 innerHTML 的区别

  • document.write 只能重绘整个页面

  • innerHTML 可以重绘页面的一部分 ## 哪些操作会造成内存泄露

  • setTimeout 的第一个参数使用字符串不是函数的话,会引发内存泄露。

  • 闭包。

  • 控制台的日志。

事件委托

本来改自己干的事自己不干交给别人。比如你要给很多 li 添加事件,我们委托给一个 button 按钮。

jsonp 是什么

动态创建 script 标签, 利用回调函数配合 js 渲染页面。

javascript 中的垃圾回收机制

在 javascript 中,如果一个对象不再被引用,那么这个对象就会被回收。如果两个对象互相引用,而不再被第三者引用,那么这两个互相引用的对象也会被回收。

好了,就先到这里,我先打把王者放松一下手指,下一篇 (jQuery)